---
## /integrate/curators/deploy-vault
import { Details } from "../../../components/Details";
import { Tabs, TabItem } from "../../../components/Tabs";
# Deploy Vault
Symbiotic is a highly modular protocol that already has a lot of separate parts and will have much more in the future. Therefore, this guide describes possible configurations of the Vault deployments.
## General-purpose deployment
The first step for the ready-to-go Vault deployment is to determine how it is going to be used:
1. As a very specific configuration inside some complex system of contracts that needs to be designed and created
2. As a very pure configuration with most of the parameters non-updatable that can be hardly manageable in practice
3. **As some common configuration that may cover most of the use cases**
For our needs, we choose the 3-rd option, and the steps to get a production-ready configuration are the following:
1. Deploy a **Burner Router** which is a specific implementation of the Burner module
2. Deploy **core modules such as Vault, Delegator, Slasher** using the deployed Burner Router address
3. Deploy **staker rewards** with the use of the Vault’s address got during the previous step
### 1. Burner Router
Burner is a contract that receives slashed collateral tokens. Symbiotic does not specify the whole processing of the funds flow after the slashing. For example, there are some possible ways:
- Fully burn the funds (unwrap the underlying assets if needed)
- Redistribute to good operators
- Compensate the victims (in case of using the stake as a security deposit)
From our side, we provide:
- **DefaultBurners** - pure burner contracts for several ETH LSTs
- **BurnerRouter** - a router contract that allows redirection of the slashed funds to different addresses depending on the slashing networks and the slashed operators
Our pure burners have one advantage and disadvantage simultaneously - they are fully immutable, removing any trust assumptions in that direction. However, in case of the underlying LST’s upgrade of the contracts, their flow may break. Therefore, in general, we suggest using **BurnerRouter**, which contains the receivers’ update functionality, in pair with a **DefaultBurner** as a global receiver.

1. Clone the burners repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/burners.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd burners
```
3. Deploy a burner router contract using [a simple script](https://github.com/symbioticfi/burners/blob/main/script/deploy/BurnerRouter.s.sol):
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0xdCaC890b14121FD5D925E2589017Be68C2B5B324 # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0x8d09a4502Cc8Cf1547aD300E066060D043f6982D # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-hoodi.gateway.tatum.io \
--chain hoodi \
--broadcast
```
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0xB82381A3fBD3FaFA77B3a7bE693342618240067b # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0x58D347334A5E6bDE7279696abE59a11873294FA4 # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the burners repository by running the following command:
```bash [bash]
forge install symbioticfi/burners
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/burners/=lib/burners/
```
3. Create a burner router contract using [a BurnerRouterFactory contract](https://github.com/symbioticfi/burners/blob/main/src/contracts/router/BurnerRouterFactory.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0x99F2B89fB3C363fBafD8d826E5AA77b28bAB70a0; // address of the BurnerRouterFactory (see Deployments page)
// ...
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0xdCaC890b14121FD5D925E2589017Be68C2B5B324, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: new IBurnerRouter.NetworkReceiver[](0), // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0xF619c99D166224B4AC008b14Cc67ac72C2E91D8a; // address of the BurnerRouterFactory (see Deployments page)
// ...
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0x8d09a4502Cc8Cf1547aD300E066060D043f6982D, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: new IBurnerRouter.NetworkReceiver[](0), // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0x32e2AfbdAffB1e675898ABA75868d92eE1E68f3b; // address of the BurnerRouterFactory (see Deployments page)
// ...
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0xB82381A3fBD3FaFA77B3a7bE693342618240067b, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0x58D347334A5E6bDE7279696abE59a11873294FA4, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: new IBurnerRouter.NetworkReceiver[](0), // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
### 2. Core modules
#### Vault
Vault is a contract that:
- storages the collateral
- performs accounting in the sense of deposits and withdrawals
- processes slashing events by transferring the collateral to the burner
- allows deposit whitelisting and deposit limiting
For now, there are two types of Vaults we provide:
1. **Vault (version 1)** - is a standard version of the Vault that is responsible for all of the functions mentioned above
2. **Tokenized Vault (version 2)** - is an extended version of the Vault that represents stake shares as ERC-20 tokens
In general, we don’t need the tokenization of the stake as LRTs provide it. Therefore, we will use the common **Vault**.

:::info
It is also possible to deploy a Vault using our [form](https://app.symbiotic.fi/create).
:::
#### Delegator
Delegator is a contract that allows Vault curator to allocate the stake to networks and operators.
At the current moment, we have four types of it:
1. **NetworkRestakeDelegator (type 0)** - it accounts for allocations in absolute numbers for networks and in shares for operator-network pairs, so it allows having a staking and a common restaking across the networks (depending on the delegated amounts)
2. **FullRestakeDelegator (type 1)** - it accounts for allocations in absolute numbers for both: networks and operator-network pairs, so it allows everything that NetworkRestakeDelegator allows and restaking across the operators inside the networks as an addition
3. **OperatorSpecificDelegator (type 2)** - it is a simplified version of NetworkRestakeDelegator where only one specific operator has allocations
4. **OperatorNetworkSpecificDelegator (type 3)** - it is the most simple version where only one specific operator at one specific network has an allocation
FullRestakeDelegator is able to cover all the delegation use cases. However, it is also able to create highly risky configurations that need proper handling. OperatorSpecificDelegator limits the possible use cases for LRTs with a non-single number of operators, and OperatorNetworkSpecificDelegator has more limitations than the previous one by design. Hence, let’s choose **NetworkRestakeDelegator** for our needs.
:::info
Multi-operator Single-Network Vault can be achieved by having Network-Restake delegator with disabled NetworkLimitSet role
:::

#### Slasher
Slasher is a contract that is responsible for the proper penalty execution, preserving networks’ rights to be able to slash the captured stake and preserving stakers’ rights not to be slashed more than deserved.
There are two types of Slasher:
1. **Slasher (type 0)** - is a common Slasher that receives slashing requests and instantly executes them
2. **VetoSlasher (type 1)** - it allows to veto received slashing requests using resolvers
For the VetoSlasher, networks may propose resolvers that can veto the slashing requests. **It is also possible for the networks not to set a resolver that enables an instant slashing mechanic similar to Slasher’s.** If the Vault curator is not ready to provide a stake without the resolver, the curator may simply not allocate any stake to such networks. Since the **VetoSlasher** can be seen as an extension of the Slasher, we’ll choose it.

1. Clone the core contracts repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/core.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd core
```
3. Deploy core modules contracts using a simple script:
Open [DeployVault.s.sol](https://github.com/symbioticfi/core/blob/main/script/DeployVault.s.sol), you will see the following config:
```bash [bash]
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
address OWNER = 0x0000000000000000000000000000000000000000;
// Address of the collateral token
address COLLATERAL = 0x0000000000000000000000000000000000000000;
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
address BURNER = 0x000000000000000000000000000000000000dEaD;
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
uint48 EPOCH_DURATION = 7 days;
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
uint64 DELEGATOR_INDEX = 0;
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
address[] NETWORK_ALLOCATION_SETTERS_OR_NETWORK = [0x0000000000000000000000000000000000000000];
// Setting depending on the delegator type:
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
address[] OPERATOR_ALLOCATION_SETTERS_OR_OPERATOR = [0x0000000000000000000000000000000000000000];
// Whether to deploy a slasher
bool WITH_SLASHER = true;
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
uint64 SLASHER_INDEX = 1;
// Duration of a veto period (should be less than EPOCH_DURATION)
uint48 VETO_DURATION = 1 days;
// Optional
// Deposit limit (maximum amount of the active stake allowed in the vault)
uint256 DEPOSIT_LIMIT = 0;
// Addresses of the whitelisted depositors
address[] WHITELISTED_DEPOSITORS = new address[](0);
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
address HOOK = 0x0000000000000000000000000000000000000000;
// Delay in epochs for a network to update a resolver
uint48 RESOLVER_SET_EPOCHS_DELAY = 3;
```
Edit needed fields, and execute the script via:
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://0xrpc.io/hoodi \
--chain hoodi \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the core contracts repository by running the following command:
```bash [bash]
forge install symbioticfi/core
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/core/=lib/core/
```
3. Create core modules using [a VaultConfigurator contract](https://github.com/symbioticfi/core/blob/main/src/contracts/VaultConfigurator.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DeployVault.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x29300b1d3150B4E2b12fE80BE72f365E200441EC; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
```solidity [DeployVault.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x94c344E816A53D07fC4c7F4a18f82b6Da87CFc8f; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x8d09a4502Cc8Cf1547aD300E066060D043f6982D, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
```solidity [DeployVault.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0xD2191FE92987171691d552C219b8caEf186eb9cA; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0xB82381A3fBD3FaFA77B3a7bE693342618240067b, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
### 3. Staker rewards
Rewards logic is not enshrined in the core contract, and we allow anyone to create their own implementations if needed. However, it requires resources like time, knowledge, and money. Therefore, we provide a default implementation of the staker rewards named **DefaultStakerRewards**. Its main goals are:
- allow networks to distribute rewards for the stakers of the certain Vault
- allow stakers to claim these rewards
- allow Vault curators to receive fees from the distributed rewards
It is the only staker rewards implementation we provided, so let’s add it to our deployment configuration.

1. Clone the rewards contracts repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/rewards.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd rewards
```
3. Deploy a staker rewards contract using [a simple script](https://github.com/symbioticfi/rewards/blob/main/script/deploy/DefaultStakerRewards.s.sol):
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
```bash [bash]
VAULT= # address of the deployed Vault
ADMIN_FEE=1000 # admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
ADMIN=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the main admin (can manage all roles)
ADMIN_FEE_CLAIMER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee claimer
ADMIN_FEE_SETTER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee setter
forge script script/deploy/DefaultStakerRewards.s.sol:DefaultStakerRewardsScript \
$VAULT \
$ADMIN_FEE \
$ADMIN \
$ADMIN_FEE_CLAIMER \
$ADMIN_FEE_SETTER \
--sig "run(address,uint256,address,address,address)" \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
VAULT= # address of the deployed Vault
ADMIN_FEE=1000 # admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
ADMIN=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the main admin (can manage all roles)
ADMIN_FEE_CLAIMER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee claimer
ADMIN_FEE_SETTER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee setter
forge script script/deploy/DefaultStakerRewards.s.sol:DefaultStakerRewardsScript \
$VAULT \
$ADMIN_FEE \
$ADMIN \
$ADMIN_FEE_CLAIMER \
$ADMIN_FEE_SETTER \
--sig "run(address,uint256,address,address,address)" \
--rpc-url=https://ethereum-hoodi.gateway.tatum.io \
--chain hoodi \
--broadcast
```
```bash [bash]
VAULT= # address of the deployed Vault
ADMIN_FEE=1000 # admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
ADMIN=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the main admin (can manage all roles)
ADMIN_FEE_CLAIMER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee claimer
ADMIN_FEE_SETTER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the admin fee setter
forge script script/deploy/DefaultStakerRewards.s.sol:DefaultStakerRewardsScript \
$VAULT \
$ADMIN_FEE \
$ADMIN \
$ADMIN_FEE_CLAIMER \
$ADMIN_FEE_SETTER \
--sig "run(address,uint256,address,address,address)" \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the rewards contracts repository by running the following command:
```bash [bash]
forge install symbioticfi/rewards
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/rewards/=lib/rewards/
```
3. Create a staker rewards contract using [a DefaultStakerRewardsFactory contract](https://github.com/symbioticfi/rewards/blob/main/src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DefaultStakerRewards.s.sol]
import {IDefaultStakerRewardsFactory} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol";
import {IDefaultStakerRewards} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
// ...
address DEFAULT_STAKER_REWARDS_FACTORY = 0x290CAB97a312164Ccf095d75D6175dF1C4A0a25F; // address of the DefaultStakerRewardsFactory (see Deployments page)
// ...
address defaultStakerRewards = IDefaultStakerRewardsFactory(DEFAULT_STAKER_REWARDS_FACTORY).create(IDefaultStakerRewards.InitParams({
vault: , // address of the deployed Vault
adminFee: 1000, // admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the main admin (can manage all roles)
adminFeeClaimRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the admin fee claimer
adminFeeSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the admin fee setter
}));
// ...
```
```solidity [DefaultStakerRewards.s.sol]
import {IDefaultStakerRewardsFactory} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol";
import {IDefaultStakerRewards} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
// ...
address DEFAULT_STAKER_REWARDS_FACTORY = 0x698C36DE44D73AEfa3F0Ce3c0255A8667bdE7cFD; // address of the DefaultStakerRewardsFactory (see Deployments page)
// ...
address defaultStakerRewards = IDefaultStakerRewardsFactory(DEFAULT_STAKER_REWARDS_FACTORY).create(IDefaultStakerRewards.InitParams({
vault: , // address of the deployed Vault
adminFee: 1000, // admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the main admin (can manage all roles)
adminFeeClaimRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the admin fee claimer
adminFeeSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the admin fee setter
}));
// ...
```
```solidity [DefaultStakerRewards.s.sol]
import {IDefaultStakerRewardsFactory} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol";
import {IDefaultStakerRewards} from "@symbioticfi/rewards/src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
// ...
address DEFAULT_STAKER_REWARDS_FACTORY = 0x70C618a13D1A57f7234c0b893b9e28C5cA8E7f37; // address of the DefaultStakerRewardsFactory (see Deployments page)
// ...
address defaultStakerRewards = IDefaultStakerRewardsFactory(DEFAULT_STAKER_REWARDS_FACTORY).create(IDefaultStakerRewards.InitParams({
vault: , // address of the deployed Vault
adminFee: 1000, // admin fee percent to get from all the rewards distributions (10% = 1_000 | 100% = 10_000)
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the main admin (can manage all roles)
adminFeeClaimRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the admin fee claimer
adminFeeSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the admin fee setter
}));
// ...
```
## Advanced
### Network-specific burners
The further text describes extended configurations that may bring risk reductions, wider support of the networks, and more capital efficiency for users.
Such a case is possible:
- In general, a Vault wants the slashed funds to be burnt.
- On the other hand, there is a highly reputable network that wants its slashings to be redistributed across the users who could suffer losses because of the operators’ malicious activity.
- The Vault decides to integrate such a network to increase its capital efficiency.
Right now, our configuration doesn’t contain such logic, but it can already support it. [As mentioned earlier](#1-burner-router), **BurnerRouter** allows splitting the slashed funds across any number of receivers depending on the slashing networks and the slashed operators. Therefore, given the network address that needs such functionality and the burner address to send the funds to, it is possible to either configure such behavior using an already existing burner router or take care of it during the deployment.
:::warning
In general, burning the slashed funds is one of the safest ways to go. Any other methodology for processing the slashed funds may create incentives for different parties to trigger the slashing, depending on many factors.
:::

1. Clone the burners repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/burners.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd burners
```
3. Deploy a burner router contract with a preconfigured network-specific burner using [a simple script](https://github.com/symbioticfi/burners/blob/main/script/deploy/BurnerRouter.s.sol):
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0xdCaC890b14121FD5D925E2589017Be68C2B5B324 # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[\(,\)] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0x8d09a4502Cc8Cf1547aD300E066060D043f6982D # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[\(,\)] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-hoodi.gateway.tatum.io \
--chain hoodi \
--broadcast
```
```bash [bash]
OWNER=0xe8616DEcea16b5216e805B0b8caf7784de7570E7 # address of the router’s owner
COLLATERAL=0xB82381A3fBD3FaFA77B3a7bE693342618240067b # address of the collateral - wstETH (MUST be the same as for the Vault to connect)
DELAY=1814400 # duration of the receivers’ update delay (= 21 days)
GLOBAL_RECEIVER=0x58D347334A5E6bDE7279696abE59a11873294FA4 # address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
NETWORK_RECEIVERS=[\(,\)] # array with elements like "\(network_address,receiver_address\)" meaning network-specific receivers
OPERATOR_NETWORK_RECEIVERS=[] # array with elements like "\(network_address,operator_address,receiver_address\)" meaning operator-network-specific receivers
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript \
$OWNER \
$COLLATERAL \
$DELAY \
$GLOBAL_RECEIVER \
$NETWORK_RECEIVERS \
$OPERATOR_NETWORK_RECEIVERS \
--sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the burners repository by running the following command:
```bash [bash]
forge install symbioticfi/burners
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/burners/=lib/burners/
```
3. Create a burner router contract using [a BurnerRouterFactory contract](https://github.com/symbioticfi/burners/blob/main/src/contracts/router/BurnerRouterFactory.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0x99F2B89fB3C363fBafD8d826E5AA77b28bAB70a0; // address of the BurnerRouterFactory (see Deployments page)
// ...
IBurnerRouter.NetworkReceiver[] memory networkReceivers = new IBurnerRouter.NetworkReceiver[](1);
networkReceivers[0] = IBurnerRouter.NetworkReceiver({
network: ,
receiver:
});
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0xdCaC890b14121FD5D925E2589017Be68C2B5B324, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: networkReceivers, // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0xF619c99D166224B4AC008b14Cc67ac72C2E91D8a; // address of the BurnerRouterFactory (see Deployments page)
// ...
IBurnerRouter.NetworkReceiver[] memory networkReceivers = new IBurnerRouter.NetworkReceiver[](1);
networkReceivers[0] = IBurnerRouter.NetworkReceiver({
network: ,
receiver:
});
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0x8d09a4502Cc8Cf1547aD300E066060D043f6982D, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: networkReceivers, // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
```solidity [DeployBurnerRouter.s.sol]
import {IBurnerRouterFactory} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouterFactory.sol";
import {IBurnerRouter} from "@symbioticfi/burners/src/interfaces/router/IBurnerRouter.sol";
// ...
address BURNER_ROUTER_FACTORY = 0x32e2AfbdAffB1e675898ABA75868d92eE1E68f3b; // address of the BurnerRouterFactory (see Deployments page)
// ...
IBurnerRouter.NetworkReceiver[] memory networkReceivers = new IBurnerRouter.NetworkReceiver[](1);
networkReceivers[0] = IBurnerRouter.NetworkReceiver({
network: ,
receiver:
});
address burnerRouter = IBurnerRouterFactory(BURNER_ROUTER_FACTORY).create(
IBurnerRouter.InitParams({
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the router’s owner
collateral: 0xB82381A3fBD3FaFA77B3a7bE693342618240067b, // address of the collateral - wstETH (MUST be the same as for the Vault to connect)
delay: 1814400, // duration of the receivers’ update delay (= 21 days)
globalReceiver: 0x58D347334A5E6bDE7279696abE59a11873294FA4, // address of the pure burner corresponding to the collateral - wstETH_Burner (some collaterals are covered by us; see Deployments page)
networkReceivers: networkReceivers, // array with IBurnerRouter.NetworkReceiver elements meaning network-specific receivers
operatorNetworkReceivers: new IBurnerRouter.OperatorNetworkReceiver[](0) // array with IBurnerRouter.OperatorNetworkReceiver elements meaning network-specific receivers
})
);
// ...
```
Generally, all the changes inside the burner router can be performed in 2 steps:
1. Create a pending request to change some value
2. Accept the request after waiting for a configured `delay`
Therefore, to set a new receiver (which can be a network-specific burner or treasury or any address) for a particular network the further steps are needed:
1. Owner calls `setNetworkReceiver(network, receiver)`
2. Wait for `delay`
3. Anyone commits the change via `acceptNetworkReceiver(network)`
To set a new receiver for some exact operator inside a particular network:
1. Owner calls `setOperatorNetworkReceiver(network, operator, receiver)`
2. Wait for `delay`
3. Anyone commits the change via `acceptOperatorNetworkReceiver(network)`
To set a new global receiver that gets funds if no specific receivers for a network-operator pair are configured:
1. Owner calls `setGlobalReceiver(receiver)`
2. Wait for `delay`
3. Anyone commits the change via `acceptGlobalReceiver(network)`
To change a `delay`:
1. Owner calls `setDelay(newDelay)`
2. Wait for an old `delay`
3. Anyone commits the change via `acceptDelay()`
### Hook
Hook is a contract that the Vault curator can set to receive `onSlash()` call on each slashing event. Symbiotic doesn’t specify any logic behind it. However, the basic idea of the hook is to allow the creation of any delegation adjustment mechanic during the slashing.
:::warning
Symbiotic Delegator contracts don’t update allocations on the slashing events in any way. This means that a malicious network or an operator may need only several blocks (depending on their allocated stake) to slash all of Vault’s funds.
:::
We provide pure **example** implementations of some standard adjustment mechanics for each Delegator type - [here](https://github.com/symbioticfi/hooks).

1. Clone the core contracts repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/core.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd core
```
3. Deploy core modules contracts using a simple script:
Open [DeployVault.s.sol](https://github.com/symbioticfi/core/blob/main/script/DeployVault.s.sol), you will see the following config:
```bash [bash]
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
address OWNER = 0x0000000000000000000000000000000000000000;
// Address of the collateral token
address COLLATERAL = 0x0000000000000000000000000000000000000000;
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
address BURNER = 0x000000000000000000000000000000000000dEaD;
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
uint48 EPOCH_DURATION = 7 days;
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
uint64 DELEGATOR_INDEX = 0;
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
address[] NETWORK_ALLOCATION_SETTERS_OR_NETWORK = [0x0000000000000000000000000000000000000000];
// Setting depending on the delegator type:
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
address[] OPERATOR_ALLOCATION_SETTERS_OR_OPERATOR = [0x0000000000000000000000000000000000000000];
// Whether to deploy a slasher
bool WITH_SLASHER = true;
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
uint64 SLASHER_INDEX = 1;
// Duration of a veto period (should be less than EPOCH_DURATION)
uint48 VETO_DURATION = 1 days;
// Optional
// Deposit limit (maximum amount of the active stake allowed in the vault)
uint256 DEPOSIT_LIMIT = 0;
// Addresses of the whitelisted depositors
address[] WHITELISTED_DEPOSITORS = new address[](0);
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
address HOOK = ;
// Delay in epochs for a network to update a resolver
uint48 RESOLVER_SET_EPOCHS_DELAY = 3;
```
Edit needed fields, and execute the script via:
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://0xrpc.io/hoodi \
--chain hoodi \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the core contracts repository by running the following command:
```bash [bash]
forge install symbioticfi/core
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/core/=lib/core/
```
3. Create core modules with hook using [a VaultConfigurator contract](https://github.com/symbioticfi/core/blob/main/src/contracts/VaultConfigurator.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DeployVaultWithHook.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x29300b1d3150B4E2b12fE80BE72f365E200441EC; // address of the VaultConfigurator (see Deployments page)
// ...
address hook = ;
address[] memory networkLimitSetRoleHolders = new address[](2);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
networkLimitSetRoleHolders[1] = hook;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](2);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
operatorNetworkSharesSetRoleHolders[1] = hook;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: hook, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
```solidity [DeployVaultWithHook.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x94c344E816A53D07fC4c7F4a18f82b6Da87CFc8f; // address of the VaultConfigurator (see Deployments page)
// ...
address hook = ;
address[] memory networkLimitSetRoleHolders = new address[](2);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
networkLimitSetRoleHolders[1] = hook;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](2);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
operatorNetworkSharesSetRoleHolders[1] = hook;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: hook, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
```solidity [DeployVaultWithHook.s.sol]
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0xD2191FE92987171691d552C219b8caEf186eb9cA; // address of the VaultConfigurator (see Deployments page)
// ...
address hook = ;
address[] memory networkLimitSetRoleHolders = new address[](2);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
networkLimitSetRoleHolders[1] = hook;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](2);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
operatorNetworkSharesSetRoleHolders[1] = hook;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: false, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: hook, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
// ...
```
1. We need the address of the Vault’s Delegator contract. It can be obtained via `Vault.delegator()`
2. Make sure the caller has a `Delegator.HOOK_SET_ROLE()` role via [the OpenZeppelin’s `AccessControl` contract](https://docs.openzeppelin.com/contracts/5.x/access-control#using-access-control)
3. Call `Delegator.setHook(hook)`
### Deposit whitelist
Symbiotic Vaults contain a feature called - deposit whitelist. It allows the restriction of making deposits to the Vault only by the whitelisted depositors. Several parties may need such functionality, e.g.:
1. LRTs that want to fully isolate their Vaults from the external users to have a strict logic flow depending only on them
2. Institutional entities that want to reduce the risks maximally and respect the legal side
3. Some third-party entities that want to integrate the Vaults with some specific logic on top of them

1. Clone the core contracts repository by running the following command:
```bash [bash]
git clone --recurse-submodules https://github.com/symbioticfi/core.git
```
2. Navigate into the cloned repository folder:
```bash [bash]
cd core
```
3. Deploy core modules contracts using a simple script:
Open [DeployVault.s.sol](https://github.com/symbioticfi/core/blob/main/script/DeployVault.s.sol), you will see the following config:
```bash [bash]
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
address OWNER = 0x0000000000000000000000000000000000000000;
// Address of the collateral token
address COLLATERAL = 0x0000000000000000000000000000000000000000;
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
address BURNER = 0x000000000000000000000000000000000000dEaD;
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
uint48 EPOCH_DURATION = 7 days;
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
uint64 DELEGATOR_INDEX = 0;
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
address[] NETWORK_ALLOCATION_SETTERS_OR_NETWORK = [0x0000000000000000000000000000000000000000];
// Setting depending on the delegator type:
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
address[] OPERATOR_ALLOCATION_SETTERS_OR_OPERATOR = [0x0000000000000000000000000000000000000000];
// Whether to deploy a slasher
bool WITH_SLASHER = true;
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
uint64 SLASHER_INDEX = 1;
// Duration of a veto period (should be less than EPOCH_DURATION)
uint48 VETO_DURATION = 1 days;
// Optional
// Deposit limit (maximum amount of the active stake allowed in the vault)
uint256 DEPOSIT_LIMIT = 0;
// Addresses of the whitelisted depositors
address[] WHITELISTED_DEPOSITORS = ;
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
address HOOK = 0x0000000000000000000000000000000000000000;
// Delay in epochs for a network to update a resolver
uint48 RESOLVER_SET_EPOCHS_DELAY = 3;
```
Edit needed fields, and execute the script via:
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-rpc.publicnode.com \
--chain mainnet \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://0xrpc.io/hoodi \
--chain hoodi \
--broadcast
```
```bash [bash]
forge script script/DeployVault.s.sol:DeployVaultScript \
--rpc-url=https://ethereum-sepolia-rpc.publicnode.com \
--chain sepolia \
--broadcast
```
:::note
It is an **example** command, meaning you need to replace the given values with necessary ones.
***
In addition, you need to [choose a preferred wallet option](https://book.getfoundry.sh/reference/forge/forge-script?highlight=forge%20script#wallet-options---raw) and adjust the command accordingly.
:::
The following instruction assumes you have an already initialized Foundry repository ([read more here](https://book.getfoundry.sh/getting-started/first-steps)).
1. Install the core contracts repository by running the following command:
```bash [bash]
forge install symbioticfi/core
```
2. Update (or create if not yet) a `remappings.txt` file inside your repository accordingly:
```txt title="remappings.txt"
...
@symbioticfi/core/=lib/core/
```
3. Create core modules with deposit whitelist using [a VaultConfigurator contract](https://github.com/symbioticfi/core/blob/main/src/contracts/VaultConfigurator.sol):
:::note
It is an **example** code snippet, meaning you need to replace the given values with necessary ones.
:::
```solidity [DeployVaultWithWhitelist.s.sol]
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x29300b1d3150B4E2b12fE80BE72f365E200441EC; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: true, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: address(this), // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
Vault(vault).grantRole(Vault(vault).DEFAULT_ADMIN_ROLE(), 0xe8616DEcea16b5216e805B0b8caf7784de7570E7);
Vault(vault).grantRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
IVault(vault).setDepositorWhitelistStatus(, true);
Vault(vault).renounceRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
Vault(vault).renounceRole(Vault(vault).DEFAULT_ADMIN_ROLE(), address(this));
// ...
```
```solidity [DeployVaultWithWhitelist.s.sol]
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0x94c344E816A53D07fC4c7F4a18f82b6Da87CFc8f; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0x8d09a4502Cc8Cf1547aD300E066060D043f6982D, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: true, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: address(this), // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
Vault(vault).grantRole(Vault(vault).DEFAULT_ADMIN_ROLE(), 0xe8616DEcea16b5216e805B0b8caf7784de7570E7);
Vault(vault).grantRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
IVault(vault).setDepositorWhitelistStatus(, true);
Vault(vault).renounceRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
Vault(vault).renounceRole(Vault(vault).DEFAULT_ADMIN_ROLE(), address(this));
// ...
```
```solidity [DeployVaultWithWhitelist.s.sol]
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
// ...
address VAULT_CONFIGURATOR = 0xD2191FE92987171691d552C219b8caEf186eb9cA; // address of the VaultConfigurator (see Deployments page)
// ...
address[] memory networkLimitSetRoleHolders = new address[](1);
networkLimitSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
address[] memory operatorNetworkSharesSetRoleHolders = new address[](1);
operatorNetworkSharesSetRoleHolders[0] = 0xe8616DEcea16b5216e805B0b8caf7784de7570E7;
(address vault, address networkRestakeDelegator, address vetoSlasher) = IVaultConfigurator(VAULT_CONFIGURATOR).create(
IVaultConfigurator.InitParams({
version: 1, // Vault’s version (= common one)
owner: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Vault’s owner (can migrate the Vault to new versions in the future)
vaultParams: abi.encode(IVault.InitParams({
collateral: 0xB82381A3fBD3FaFA77B3a7bE693342618240067b, // address of the collateral - wstETH
burner: , // address of the deployed burner router
epochDuration: 604800, // duration of the Vault epoch in seconds (= 7 days)
depositWhitelist: true, // if enable deposit whitelisting
isDepositLimit: false, // if enable deposit limit
depositLimit: 0, // deposit limit
defaultAdminRoleHolder: address(this), // address of the Vault’s admin (can manage all roles)
depositWhitelistSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit whitelisting
depositorWhitelistRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the depositors whitelister
isDepositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the enabler/disabler of the deposit limit
depositLimitSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the deposit limit setter
})),
delegatorIndex: 0, // Delegator’s type (= NetworkRestakeDelegator)
delegatorParams: abi.encode(INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({
defaultAdminRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7, // address of the Delegator’s admin (can manage all roles)
hook: 0x0000000000000000000000000000000000000000, // address of the hook (if not zero, receives onSlash() call on each slashing)
hookSetRoleHolder: 0xe8616DEcea16b5216e805B0b8caf7784de7570E7 // address of the hook setter
}),
networkLimitSetRoleHolders: networkLimitSetRoleHolders, // array of addresses of the network limit setters
operatorNetworkSharesSetRoleHolders: operatorNetworkSharesSetRoleHolders // array of addresses of the operator-network shares setters
})),
withSlasher: true, // if enable Slasher module
slasherIndex: 1, // Slasher’s type (= VetoSlasher)
slasherParams: abi.encode(IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({
isBurnerHook: true // if enable the `burner` to receive onSlash() call after each slashing (is needed for the burner router workflow)
}),
vetoDuration: 86400, // veto duration (= 1 day)
resolverSetEpochsDelay: 3 // number of Vault epochs needed for the resolver to be changed
}))
})
);
Vault(vault).grantRole(Vault(vault).DEFAULT_ADMIN_ROLE(), 0xe8616DEcea16b5216e805B0b8caf7784de7570E7);
Vault(vault).grantRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
IVault(vault).setDepositorWhitelistStatus(, true);
Vault(vault).renounceRole(Vault(vault).DEPOSITOR_WHITELIST_ROLE(), address(this));
Vault(vault).renounceRole(Vault(vault).DEFAULT_ADMIN_ROLE(), address(this));
// ...
```
1. Make sure the caller has a `Vault.DEPOSIT_WHITELIST_SET_ROLE()` role via [the OpenZeppelin’s `AccessControl` contract](https://docs.openzeppelin.com/contracts/5.x/access-control#using-access-control)
2. Call `Vault.setDepositWhitelist(true)`
3. Make sure the caller has a `Vault.DEPOSITOR_WHITELIST_ROLE()` role via [the OpenZeppelin’s `AccessControl` contract](https://docs.openzeppelin.com/contracts/5.x/access-control#using-access-control)
4. Call `Vault.setDepositorWhitelistStatus(account, true)`
---
## /integrate/curators/helpful-core-contracts-endpoints
# Helpful Core Contracts' Endpoints
This page provides a list of useful in practice functions for a Network across Symbiotic Core contracts.
| Function | Use-case |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| [`create(InitParams params) -> address, address, address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/IVaultConfigurator.sol#L52) | Create a new Vault |
| [`Vault.delegator() → address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/vault/IVaultStorage.sol#L60) | Get the Vault's delegator |
| [`Vault.slasher() → address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/vault/IVaultStorage.sol#L72) | Get the Vault's slasher |
| [`BaseDelegator.TYPE() → uint64`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/common/IEntity.sol#L17) | Get the delegator's type (0 - NetworkRestake, 1 - FullRestake, etc.) |
| [`BaseDelegator.stake(bytes32 subnetwork, address operator) → uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IBaseDelegator.sol#L150) | Get the operator-network's stake |
| [`NetworkRestakeDelegator.setNetworkLimit(bytes32 subnetwork, uint256 amount)`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/INetworkRestakeDelegator.sol#L136) | Set a amount of collateral to allocate to the network |
| [`NetworkRestakeDelegator.networkLimit(bytes32 subnetwork) -> uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/INetworkRestakeDelegator.sol#L84) | Check the network's allocation |
| [`NetworkRestakeDelegator.setOperatorNetworkShares(bytes32 subnetwork, address operator, uint256 shares) `](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/INetworkRestakeDelegator.sol#L147) | Set the operator's share from the network's allocation |
| [`NetworkRestakeDelegator.operatorNetworkShares(bytes32 subnetwork, address operator) -> uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/INetworkRestakeDelegator.sol#L128) | Check the operator-network's shares |
| [`FullRestakeDelegator.setNetworkLimit(bytes32 subnetwork, uint256 amount)`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IFullRestakeDelegator.sol#L112) | Set a amount of collateral to allocate to the network |
| [`FullRestakeDelegator.networkLimit(bytes32 subnetwork) -> uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IFullRestakeDelegator.sol#L81) | Check the network's allocation |
| [`NetworkRestakeDelegator.setOperatorNetworkLimit(bytes32 subnetwork, address operator, uint256 amount)`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IFullRestakeDelegator.sol#L122) | Set the operator's limit over the network's allocation |
| [`NetworkRestakeDelegator.operatorNetworkLimit(bytes32 subnetwork, address operator) -> uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IFullRestakeDelegator.sol#L104) | Check the operator-network's limit |
| [`OperatorSpecificDelegator.setNetworkLimit(bytes32 subnetwork, uint256 amount)`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IOperatorSpecificDelegator.sol#L85) | Set a amount of collateral to allocate to the network |
| [`OperatorSpecificDelegator.networkLimit(bytes32 subnetwork) -> uint256`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IOperatorSpecificDelegator.sol#L77) | Check the network's allocation |
| [`OperatorSpecificDelegator.operator() -> address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IOperatorSpecificDelegator.sol#L60) | Check the operator who receive all the allocations |
| [`OperatorSpecificDelegator.network() -> address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol#L44) | Check the network who receive all the allocations |
| [`OperatorSpecificDelegator.operator() -> address`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol#L50) | Check the operator who receive all the allocations |
| [`BaseSlasher.TYPE() → uint64`](https://github.com/symbioticfi/core/blob/7cb06639c5cd656d1d212dafa2c270b5fde39306/src/interfaces/common/IEntity.sol#L17) | Get the slasher's type (0 - Slasher, 1 - VetoSlasher) |
---
## /integrate/curators
import { Card1 } from "../../../components/Card1";
# Get Started
Symbiotic protocol contains a wide range of supportive tooling for various curation needs. This page provides you a high-level overview of a Curator's lifecycle in Symbiotic:
:::steps
## Deploy Vault
}
href="/integrate/curators/deploy-vault"
/>
## Submit Metadata
}
href="/integrate/curators/submit-metadata"
/>
## Opt Into Networks And Vaults
}
href="/integrate/operators/opt-ins"
/>
:::
---
## /integrate/curators/manage-allocations
# Manage Allocations
Curators must perform two actions:
- Set network allocation - determining how much funds to delegate to each network
- Set operator shares within each network - specifying how the network's allocation is distributed among operators
## Set initial network delegation
### Using [Safe](https://app.safe.global/)
- Open “Transaction builder”
- Get the delegator contract address of the desired vault (using UI, CLI, or etherscan)
- Put the delegator’s address as contract address
- Click “Use Implementation ABI”
- Choose `setNetworkLimit()` method
- the desired subnetwork (which is an address of the network concatenated with the uint96 identifier)
- the desired maximum amount of collateral to allocate to the subnetwork
- Sign & send transaction
### Verify via Etherscan
- Open “Read Contract” tab in the delegator contract you used
- Open `networkLimit()` method
- Put `SUBNETWORK` (which is an address of the network concatenated with the uint96 identifier) in `subnetwork` parameter, and click “Query”. It should return the set amount

## Set initial operator delegation
### Using [Safe](https://app.safe.global/)
- Open “Transaction builder”
- Get the delegator contract address of the desired vault (using UI, CLI, or etherscan)
- Put the delegator’s address as contract address
- Click “Use Implementation ABI”
- Choose `setOperatorNetworkShares()` method
- the desired subnetwork (which is an address of the network concatenated with the uint96 identifier)
- the desired operator address
- the desired amount of shares to allocate to the operator (e.g, the operator having 100 shares out of a total 1000 shares for the given subnetwork means having 10% of the stake allocated to the subnetwork)
- Sign & send transaction
### Using CLI
- See [https://docs.symbiotic.fi/guides/cli/#set-operator-network-shares](https://docs.symbiotic.fi/guides/cli/#set-operator-network-shares)
Using CLI to check:
- See [https://docs.symbiotic.fi/guides/cli/#operator-network-shares](https://docs.symbiotic.fi/guides/cli/#operator-network-shares)
- Also, you may need [https://docs.symbiotic.fi/guides/cli/#total-operator-network-shares](https://docs.symbiotic.fi/guides/cli/#total-operator-network-shares)
### Verify via Etherscan
- Open “Read Contract” tab in the delegator you used
- Open `operatorNetworkShares()` method (also, you may need totalOperatorNetworkShares)
- Put `SUBNETWORK` (which is an address of the network concatenated with the uint96 identifier) in `subnetwork` parameter, `OPERATOR_ADDRESS` in `operator`, and click “Query”. It should return the set amount

---
## /integrate/curators/submit-metadata
# Submit Metadata
[Symbiotic UI](https://app.symbiotic.fi/deposit) provides users with accurate and up-to-date information about various data regarding TVL, allocations, relations between Curators, Vaults, Operators and Networks, etc. However, for the mentioned counterparties to be easily accessible and visible on the UI - their metadata should should be submitted to the corresponding repositories.
Once, the metadata is submitted, it should be reviewed and merged by the Symbiotic team. After that the new data starts to be shown publicly on the UI.
## Add a New Entity Template
### Choose a Repository
| Chain | URL |
| ------- | -------------------------------------------------------------------------------------------------- |
| Mainnet | [https://github.com/symbioticfi/metadata-mainnet](https://github.com/symbioticfi/metadata-mainnet) |
| Hoodi | [https://github.com/symbioticfi/metadata-hoodi](https://github.com/symbioticfi/metadata-hoodi) |
| Sepolia | [https://github.com/symbioticfi/metadata-sepolia](https://github.com/symbioticfi/metadata-sepolia) |
| Holešky | [https://github.com/symbioticfi/metadata-holesky](https://github.com/symbioticfi/metadata-holesky) |
### Repository Structure
The repository is organized as follows:
```
repository/
├── vaults/
│ ├── 0x/
│ │ ├── info.json
│ │ └── logo.png (optional)
├── networks/
├── operators/
├── tokens/
```
Each entity is identified by its Ethereum address (`0x...`), and its data is stored in a folder named after the address. Inside this folder, there must be a file `info.json` containing metadata, and optionally, an icon file `logo.png`.
***
### Steps to Add a New Entity
**Note: After your PR is submitted, email your PR link to [verify@symbiotic.fi](mailto\:verify@symbiotic.fi) from your official business email (domain must match that of your entity website) to allow us to confirm your identity ahead of merging your PR.**
1. **Determine the entity type**:
- Decide whether the entity belongs to `vaults`, `networks`, `operators`, `tokens` or `points`.
- If the entity is a `vault`, please be sure that it's collateral token entity is registered in the `tokens` folder before adding the vault metadata. If not, please add the token first.
2. **Register the entity in the registry**:
- Before adding metadata for vaults, networks, or operators, ensure that they are registered in their respective registries. You can find the current registry contract addresses in the [Addresses page](/get-started/resources/addresses). Unregistered entities will not be accepted.
3. **Create a new folder**:
- Navigate to the appropriate directory for the entity type.
- Create a folder named after the Ethereum address (e.g., `0x1234567890abcdef1234567890abcdef12345678`).
4. **Add the `info.json` file**:
- Include metadata in the specified format (see below).
5. **(Optional) Add an icon file**:
- If available, include a `logo.png` file with the entity’s logo.
Your PR will be reviewed by the Symbiotic team, and if approved, it will be merged into the repository. Please note that the PR will be reviewed only after the entity is checked with automated checks.
***
### File Format: `info.json`
The `info.json` file must follow this structure:
#### Required Fields
- `name` (string): The name of the entity.
- `description` (string): A brief description of the entity.
- `tags` (array of strings): Tags categorizing the entity.
- `links` (array of objects): External links related to the entity.
#### Fields for Tokens
- `cmcId` (string): The CoinMarketCap ID for the token. Used to fetch price of the token in USD.
- `permitName` (string): The `name` field for EIP-2612 support.
- `permitVersion` (string): The `version` field for EIP-2612 support.
#### Fields for Vaults
- `curatorId` (string): The ID of the curator of the vault.
- `vaultType` (string): The type of the vault. Can be one of:
- `eth-restaking`: Vaults with ETH-flavored collateral restaked across multiple networks
- `btc-restaking`: Vaults with BTC-flavored collateral restaked across multiple networks
- `network-exclusive`: Vaults exclusive to a single network
#### Supported `links` Types
Each link should include:
- `type`: The type of the link. Supported values are:
- `website`: The official website of the entity.
- `explorer`: A blockchain explorer link for the entity's Ethereum address or contract.
- `docs`: Documentation related to the entity.
- `example`: Example use cases or tutorials.
- `externalLink`: A link to be shown below the entity's name.
- `name`: A user-friendly name for the link.
- `url`: The URL of the resource.
### Icon File: `logo.png` (Optional)
If you want to include an icon for the entity, follow these guidelines:
- **File Name**: `logo.png`
- **Dimensions**: 256x256 pixels
- **Format**: PNG
Place the `logo.png` file in the same folder as the `info.json` file.
***
### Validation
Before submitting your PR, ensure the following:
1. The Ethereum address is valid:
- It must start with `0x` and be exactly 42 characters long.
2. The `info.json` file is valid:
- Use a JSON validator, such as [https://jsonlint.com/](https://jsonlint.com/).
3. The `logo.png` file (if included) meets the size requirement of **256x256 pixels**.
***
### Submitting the Pull Request
Once your files are added to the repository, create a Pull Request with the following details:
1. **Entity Type**: Specify the type (vault, network, operator, token).
2. **Ethereum Address**: Provide the address of the entity.
3. **Description**: Summarize the entity’s purpose and data.
#### Example PR Description
```
Added new token entity: 0x1234567890abcdef1234567890abcdef12345678
- **Name**: USDT
- **Description**: USDT is a stablecoin pegged to the US Dollar, widely used for trading and liquidity in cryptocurrency markets.
- **Tags**: stablecoin, usdt
- **Links**:
- [Website](https://tether.to/)
- [Etherscan](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7)
- [Tether Documentation](https://docs.tether.to/)
- **CMC ID**: 825
- **Permit Name**: USDT Permit Token
- **Permit Version**: 1
- **Icon**: Included (256x256 px)
```
***
### Review and Approval
Your PR will be reviewed to ensure:
- The `info.json` file has all required fields and valid data.
- The `logo.png` file (if included) meets the requirements.
- The metadata is accurate and well-structured.
- The submitter of the PR is from the entity in question (verified via an email with your PR link to [verify@symbiotic.fi](mailto\:verify@symbiotic.fi) from your official business email)
After approval, your changes will be merged into the repository.
## Add a Curator
:::steps
##### Create a new folder in the `/curators` directory
##### Create a new json file in the folder with the following structure:
```json [info.json]
{
"name": "My Curator",
"description": "My Curator is a curator that allows you to manage your vaults.",
"tags": ["curator", "staking"],
"links": [
{ "type": "website", "name": "Website", "url": "https://mycurator.com" },
{ "type": "twitter", "name": "Twitter", "url": "https://x.com/mycurator" },
{
"type": "explorer",
"name": "Explorer",
"url": "https://etherscan.io/address/0x1234567890abcdef1234567890abcdef12345678"
}
]
}
```
##### Save a logo of the Curator to `logo.png` of 256x256 pixels size
:::
## Add a Token
::::steps
##### Create a new folder in the `/tokens` directory
##### Create a new json file in the folder with the following structure:
```json [info.json]
{
"name": "My Token",
"description": "My Token is a token that allows you to earn rewards.",
"tags": ["token", "staking"],
"cmcId": "1234567890",
"links": [{ "type": "website", "name": "Website", "url": "https://mytoken.com" }]
}
```
:::warning
If the CMC ID is missing:
- The token’s price cannot be displayed
- TVL (Total Value Locked) in USD won’t be calculated
- Symbiotic Points cannot be calculated or distributed
- Points will be calculated from the date the CMC ID is added; retrospective recalculation for points accrued before this date will not occur.
:::
##### Save a logo of the Token to `logo.png` of 256x256 pixels size
::::
## Add a Vault
:::warning
If the Vault's collateral is not yet supported by Symbiotic, a separate **Token PR** must be submitted before the **Vault PR**.
:::
::::steps
##### Create a new folder in the `/vaults` directory
##### Create a new json file in the folder with the following structure:
```json [info.json]
{
"name": "DeFi Vault",
"description": "A secure vault for decentralized finance.",
"tags": ["vault", "DeFi"],
"curatorName": "My Curator",
"links": [
{
"type": "website",
"name": "Website",
"url": "https://example-vault.com/"
},
{
"type": "docs",
"name": "Vault Documentation",
"url": "https://example-vault.com/docs"
}
]
}
```
:::warning
If the CMC ID is missing:
- The token’s price cannot be displayed
- TVL (Total Value Locked) in USD won’t be calculated
- Symbiotic Points cannot be calculated or distributed
- Points will be calculated from the date the CMC ID is added; retrospective recalculation for points accrued before this date will not occur.
:::
##### Save a logo of the Vault to `logo.png` of 256x256 pixels size
::::
---
## /integrate/curators/vault-wrapping
# Vault Wrapping
Sometimes, due to design choices made regarding the Symbiotic Vault to either hold security guarantees or optimize the whole interaction flow, it's not possible to implement some your ideas in a standard way. In such cases, it is possible to wrap the Symbiotic Vault in sense of, e.g., deposits, slashing, opt-ins, etc. This page presents such example cases:
## Mortgage-backed Security Example
A **mortgage-backed security (MBS)** is a financial instrument created by pooling together many individual home loans (mortgages) and selling them as a single tradable security. Instead of a bank holding a mortgage and collecting monthly payments, the cash flows (interest and principal) from thousands of mortgages are bundled, then redistributed to investors in the MBS.
- **Tranching**: To cater to different investor risk appetites, the pool is divided into **tranches**.
- Senior tranches: Get paid first, lower risk, lower yield.
- Junior tranches: Get paid later and absorb defaults first, higher risk, higher yield.
- **Risk distribution**: This structure spreads default risk across different investor groups and creates a market for varying levels of risk exposure.
Mortgage Backed Securities Structuring and Value Chain
### Slashing Tranche-Based Vault Wrapper
In Symbiotic, **slashing vaults** are pools where collateral is staked to secure external networks or services. Just like mortgages carry **default risk**, staking carries **slashing risk** (collateral may be cut if operators misbehave).
Here’s how the analogy works:
- **Mortgages = Operator Collateral Positions**
Each mortgage in an MBS corresponds to an individual operator’s staked collateral in Symbiotic. Just as homeowners may default, operators may be slashed.
- **MBS Pool = Slashing Vault**
The pooled mortgages in an MBS map to the **vault of collateral** in Symbiotic. Both aggregate risk into a collective structure.
- **Tranches = Vault Risk Segmentation**
Symbiotic vaults could be designed with **tranches** similar to MBS:
- Senior tranche: Investors who want safer exposure get priority in withdrawals and protection against small slashes (absorbed by junior tranches first).
- Mezzanine tranche: Medium-risk exposure, takes losses only after juniors are hit.
- Junior tranche: Risk-seeking investors absorb slashing losses first but get higher yield (greater share of staking rewards).
- **Cash Flows = Staking Rewards**
Just as mortgages generate interest payments, collateral in slashing vaults generates staking rewards or fees. These flows are redistributed to participants, depending on their tranche.
- **Risk Transformation**
MBS transform mortgage default risk into tiered securities with different profiles. Symbiotic vaults could similarly transform **slashing risk** into structured exposure, letting risk-averse and risk-seeking participants coexist in the same vault.
Tranche-Based (or Slashing Insurance) Vault Segmentation + Redistribution
### Implementation
A user (staker) would have 3 choices to deposit a single ERC20 asset (collateral) into a Symbiotic vault. They can either deposit into the junior, mezzanine or senior tranche, according to their risk-profile or portfolio fit. The vault wrapper contract would then deposit the collateral to the Symbiotic vault, and the user would receive (or not, depending on the curator choice) an LST.
From our understanding, there may be 2 possibilities to issue the receipt token:
**Model A — 3 Separate ERC20s (most common in structured products)**
- When a user deposits, they **choose the tranche** (junior, mezzanine, senior).
- The wrapper mints them **only that tranche token (LST)**.
- Example:
- Alice deposits 100 USDC → gets **100 tJNR**.
- Bob deposits 100 USDC → gets **100 tSNR**.
**Model B — 1 ERC20 + internal “tranche shares” accounting**
- Users deposit into the wrapper without selecting a tranche.
- The wrapper automatically allocates the deposit across junior, mezz, and senior according to some fixed ratio (e.g., 20/30/50).
- The user receives **one unified wrapper-LST** (e.g., `tWRAP`).
Tranche-Based Vault Proposed Implementation
The entire paper, co-authored with ReSquared can be found here: [https://github.com/dias-henrique/Slashing-Insurance-Vaults/blob/main/CESIV.pdf](https://github.com/dias-henrique/Slashing-Insurance-Vaults/blob/main/CESIV.pdf)
---
## Core contracts
This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).
# File Summary
## Purpose
This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
## File Format
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A header with the file path (## File: path/to/file)
b. The full contents of the file in a code block
## Usage Guidelines
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
## Notes
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching these patterns are excluded: docs/
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)
# Directory Structure
```
.github/
ISSUE_TEMPLATE/
BUG_REPORT.yaml
FEATURE_IMPROVEMENT.yaml
workflows/
test.yaml
trufflehog.yml
CODEOWNERS
PULL_REQUEST_TEMPLATE.md
audits/
Cantina-Core.pdf
Certora-Core.pdf
ChainSecurity-Core.pdf
OtterSec-Core&Rewards.pdf
Statemind-Core&Rewards.pdf
Zellic-Core.pdf
script/
actions/
base/
OptInNetworkBase.s.sol
OptInVaultBase.s.sol
RegisterOperatorBase.s.sol
SetHookBase.s.sol
SetMaxNetworkLimitBase.s.sol
SetNetworkLimitBase.s.sol
SetOperatorNetworkSharesBase.s.sol
SetResolverBase.s.sol
VetoSlashBase.s.sol
OptInNetwork.s.sol
OptInVault.s.sol
RegisterOperator.s.sol
SetHook.s.sol
SetMaxNetworkLimit.s.sol
SetNetworkLimit.s.sol
SetOperatorNetworkShares.s.sol
SetResolver.s.sol
VetoSlash.s.sol
base/
DeployVaultBase.sol
DeployVaultTokenizedBase.sol
deploy/
base/
DeployCoreBase.s.sol
DeployHintsBase.s.sol
DeployMetadataServiceBase.s.sol
DeployNetworkMiddlewareServiceBase.s.sol
DeployNetworkRegistryBase.s.sol
DeployOperatorRegistryBase.s.sol
DeployOptInServiceBase.s.sol
DeployVaultFactoryBase.s.sol
DeployCore.s.sol
DeployHints.s.sol
DeployMetadataService.s.sol
DeployNetworkMiddlewareService.s.sol
DeployNetworkRegistry.s.sol
DeployOperatorRegistry.s.sol
DeployOptInService.s.sol
DeployVaultFactory.s.sol
integration/
examples/
OnboardNetwork.s.sol
SymbioticCoreBindings.sol
SymbioticCoreInit.sol
SymbioticInit.sol
utils/
interfaces/
ICreateX.sol
IGnosisSafe.sol
CreateXWrapper.sol
Logs.sol
ScriptBase.s.sol
Simulation.sol
sort_errors.py
sort_imports.py
DeployVault.s.sol
DeployVaultTokenized.s.sol
snapshots/
gas.txt
sizes.txt
src/
contracts/
common/
Entity.sol
Factory.sol
MigratableEntity.sol
MigratableEntityProxy.sol
MigratablesFactory.sol
Registry.sol
StaticDelegateCallable.sol
delegator/
BaseDelegator.sol
FullRestakeDelegator.sol
NetworkRestakeDelegator.sol
OperatorNetworkSpecificDelegator.sol
OperatorSpecificDelegator.sol
hints/
DelegatorHints.sol
Hints.sol
OptInServiceHints.sol
SlasherHints.sol
VaultHints.sol
libraries/
Checkpoints.sol
ERC4626Math.sol
LICENSE
Subnetwork.sol
service/
MetadataService.sol
NetworkMiddlewareService.sol
OptInService.sol
slasher/
BaseSlasher.sol
Slasher.sol
VetoSlasher.sol
vault/
Vault.sol
VaultStorage.sol
VaultTokenized.sol
DelegatorFactory.sol
NetworkRegistry.sol
OperatorRegistry.sol
SlasherFactory.sol
VaultConfigurator.sol
VaultFactory.sol
interfaces/
common/
IEntity.sol
IFactory.sol
IMigratableEntity.sol
IMigratableEntityProxy.sol
IMigratablesFactory.sol
IRegistry.sol
IStaticDelegateCallable.sol
delegator/
IBaseDelegator.sol
IDelegatorHook.sol
IFullRestakeDelegator.sol
INetworkRestakeDelegator.sol
IOperatorNetworkSpecificDelegator.sol
IOperatorSpecificDelegator.sol
service/
IMetadataService.sol
INetworkMiddlewareService.sol
IOptInService.sol
slasher/
IBaseSlasher.sol
IBurner.sol
ISlasher.sol
IVetoSlasher.sol
vault/
IVault.sol
IVaultStorage.sol
IVaultTokenized.sol
IDelegatorFactory.sol
INetworkRegistry.sol
IOperatorRegistry.sol
ISlasherFactory.sol
IVaultConfigurator.sol
IVaultFactory.sol
LICENSE
test/
common/
Entity.t.sol
Factory.t.sol
MigratableEntity.t.sol
MigratableEntityProxy.t.sol
MigratablesFactory.t.sol
Registry.t.sol
delegator/
FullRestakeDelegator.t.sol
NetworkRestakeDelegator.t.sol
OperatorNetworkSpecificDelegator.t.sol
OperatorSpecificDelegator.t.sol
integration/
actions/
ActionScripts.t.sol
ScriptBaseHarness.s.sol
base/
SymbioticCoreBindingsBase.sol
SymbioticCoreInitBase.sol
SymbioticCoreBindings.sol
SymbioticCoreBytecode.sol
SymbioticCoreConstants.sol
SymbioticCoreImports.sol
SymbioticCoreImportsContracts.sol
SymbioticCoreInit.sol
SymbioticCoreIntegration.sol
SymbioticCoreIntegrationExample.t.sol
SymbioticInit.sol
SymbioticUtils.sol
libraries/
Checkpoints.t.sol
mocks/
DAILikeToken.sol
FakeEntity.sol
FeeOnTransferToken.sol
PermitToken.sol
RebaseToken.sol
SimpleBurner.sol
SimpleEntity.sol
SimpleFullRestakeDelegatorHook.sol
SimpleMigratableEntity.sol
SimpleMigratableEntityV2.sol
SimpleNetworkRestakeDelegatorHook.sol
SimpleOperatorNetworkSpecificDelegatorHook.sol
SimpleOperatorSpecificDelegatorHook.sol
SimpleRegistry.sol
Token.sol
service/
MetadataService.t.sol
NetworkMiddlewareService.t.sol
OptInService.t.sol
slasher/
Slasher.t.sol
VetoSlasher.t.sol
vault/
Vault.t.sol
VaultTokenized.t.sol
DelegatorFactory.t.sol
NetworkRegistry.t.sol
OperatorRegistry.t.sol
POC.t.sol
POCBase.t.sol
SlasherFactory.t.sol
VaultConfigurator.t.sol
VaultFactory.t.sol
.env.example
.gitignore
.gitmodules
.pre-commit-config.yaml
.prettierignore
.prettierrc
CONTRIBUTING.md
foundry.lock
foundry.toml
LICENSE
package.json
README.md
remappings.txt
```
# Files
## File: .github/ISSUE_TEMPLATE/BUG_REPORT.yaml
````yaml
name: Bug report
description: File a bug report to help us improve the code
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Please check that the bug is not already being tracked.
- type: textarea
attributes:
label: Describe the bug
description: Provide a clear and concise description of what the bug is and which contracts it affects.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: Provide a clear and concise description of the desired fix.
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: If you have written tests to showcase the bug, what can we run to reproduce the issue?
placeholder: "git checkout / forge test --isolate --mt "
- type: textarea
attributes:
label: Additional context
description: If there is any additional context needed like a dependency or integrating contract that is affected please describe it below.
````
## File: .github/ISSUE_TEMPLATE/FEATURE_IMPROVEMENT.yaml
````yaml
name: Feature Improvement
description: Suggest an improvement.
labels: ["triage"]
body:
- type: markdown
attributes:
value: |
Please ensure that the feature has not already been requested.
- type: dropdown
attributes:
label: Component
description: Which area of code does your idea improve?
multiple: true
options:
- Gas Optimization
- General design optimization (improving efficiency, cleanliness, or developer experience)
- Testing
- Documentation
- type: textarea
attributes:
label: Describe the suggested feature and problem it solves.
description: Provide a clear and concise description of what feature you would like to see, and what problems it solves.
validations:
required: true
- type: textarea
attributes:
label: Describe the desired implementation.
description: If possible, provide a suggested architecture change or implementation.
- type: textarea
attributes:
label: Describe alternatives.
description: If possible, describe the alternatives you've considered, or describe the current functionality and how it may be sub-optimal.
- type: textarea
attributes:
label: Additional context.
description: Please list any additional dependencies or integrating contacts that are affected.
````
## File: .github/workflows/test.yaml
````yaml
name: test
on:
pull_request:
branches: [main, master, staging, dev, feat/**, fix/**]
push:
branches: [main, master, staging, dev]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
FOUNDRY_PROFILE: ${{ github.event_name == 'push' && 'ci' || 'pr' }}
ETH_RPC_URL: ${{ secrets.ETH_RPC_URL }}
jobs:
forge-test:
name: Foundry project
runs-on: ubuntu-latest
timeout-minutes: 180
steps:
- uses: bullfrogsec/bullfrog@1831f79cce8ad602eef14d2163873f27081ebfb3 # v0.8.4
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@82dee4ba654bd2146511f85f0d013af94670c4de # v1.4.0
with:
version: stable
- name: Run Forge fmt check
run: forge fmt --check
- name: Run Forge tests
run: forge test --isolate
````
## File: .github/workflows/trufflehog.yml
````yaml
name: TruffleHog
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
id-token: write
issues: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: bullfrogsec/bullfrog@1831f79cce8ad602eef14d2163873f27081ebfb3 # v0.8.4
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: TruffleHog OSS
id: trufflehog
uses: trufflesecurity/trufflehog@0f58ae7c5036094a1e3e750d18772af92821b503 # v3.90.5
with:
path: .
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
extra_args: --results=verified,unknown
````
## File: .github/CODEOWNERS
````
* @symbioticfi/contracts
````
## File: .github/PULL_REQUEST_TEMPLATE.md
````markdown
# Pull Request
## Description
Please include a summary of the change and which feature was implemented or which issue was fixed. Also, include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
### How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.
# Checklist:
- [ ] 100% test and branch coverage
- [ ] check slither or other analyzer for severe issues
- [ ] fuzz and invariant tests (when applicable)
---
### Considerations
- I have followed the [contributing guidelines](../CONTRIBUTING.md).
- My code follows the style guidelines of this project and I have run `forge fmt` and prettier to ensure the code style is valid
- I have performed a self-review of my own code
- I have commented my code, particularly in hard-to-understand areas
- I have made corresponding changes to the documentation
- I have added tests that prove my fix is effective or that my feature works
- New and existing unit tests pass locally with my changes
### Additional context
Add any other context about the pull request here.
````
## File: script/actions/base/OptInNetworkBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOptInService} from "../../../src/interfaces/service/IOptInService.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
import {SymbioticCoreConstants} from "../../../test/integration/SymbioticCoreConstants.sol";
⋮----
contract OptInNetworkBaseScript is ScriptBase {
function runBase(address network) public virtual returns (bytes memory data, address target) {
````
## File: script/actions/base/OptInVaultBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOptInService} from "../../../src/interfaces/service/IOptInService.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
import {SymbioticCoreConstants} from "../../../test/integration/SymbioticCoreConstants.sol";
⋮----
contract OptInVaultBaseScript is ScriptBase {
function runBase(address vault) public virtual returns (bytes memory data, address target) {
````
## File: script/actions/base/RegisterOperatorBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOperatorRegistry} from "../../../src/interfaces/IOperatorRegistry.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
import {SymbioticCoreConstants} from "../../../test/integration/SymbioticCoreConstants.sol";
⋮----
contract RegisterOperatorBaseScript is ScriptBase {
function runBase() public virtual returns (bytes memory data, address target) {
````
## File: script/actions/base/SetHookBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "../../../src/interfaces/delegator/IBaseDelegator.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract SetHookBaseScript is ScriptBase {
function runBase(address vault, address hook) public virtual returns (bytes memory data, address target) {
````
## File: script/actions/base/SetMaxNetworkLimitBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {IBaseDelegator} from "../../../src/interfaces/delegator/IBaseDelegator.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract SetMaxNetworkLimitBaseScript is ScriptBase {
function runBase(address vault, uint96 identifier, uint256 maxNetworkLimit)
````
## File: script/actions/base/SetNetworkLimitBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "../../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract SetNetworkLimitBaseScript is ScriptBase {
function runBase(address vault, bytes32 subnetwork, uint256 networkLimit)
````
## File: script/actions/base/SetOperatorNetworkSharesBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "../../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract SetOperatorNetworkSharesBaseScript is ScriptBase {
function runBase(address vault, bytes32 subnetwork, address operator, uint256 operatorNetworkShares)
````
## File: script/actions/base/SetResolverBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {IVetoSlasher} from "../../../src/interfaces/slasher/IVetoSlasher.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract SetResolverBaseScript is ScriptBase {
function runBase(address vault, uint96 identifier, address resolver)
````
## File: script/actions/base/VetoSlashBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {IVetoSlasher} from "../../../src/interfaces/slasher/IVetoSlasher.sol";
import {Logs} from "../../utils/Logs.sol";
import {ScriptBase} from "../../utils/ScriptBase.s.sol";
⋮----
contract VetoSlashBaseScript is ScriptBase {
function runBase(address vault, uint256 slashIndex) public virtual returns (bytes memory data, address target) {
````
## File: script/actions/OptInNetwork.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/OptInNetworkBase.s.sol";
⋮----
// forge script script/actions/OptInNetwork.s.sol:OptInNetworkScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/OptInNetwork.s.sol:OptInNetworkScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract OptInNetworkScript is OptInNetworkBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Network to opt into
⋮----
function run() public {
````
## File: script/actions/OptInVault.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/OptInVaultBase.s.sol";
⋮----
// forge script script/actions/OptInVault.s.sol:OptInVaultScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/OptInVault.s.sol:OptInVaultScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract OptInVaultScript is OptInVaultBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault to opt into
⋮----
function run() public {
````
## File: script/actions/RegisterOperator.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/RegisterOperatorBase.s.sol";
⋮----
// forge script script/actions/RegisterOperator.s.sol:RegisterOperatorScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/RegisterOperator.s.sol:RegisterOperatorScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract RegisterOperatorScript is RegisterOperatorBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Nothing to configure
⋮----
function run() public {
````
## File: script/actions/SetHook.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/SetHookBase.s.sol";
⋮----
// forge script script/actions/SetHook.s.sol:SetHookScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/SetHook.s.sol:SetHookScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract SetHookScript is SetHookBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault to update
⋮----
// Address of the hook contract to set
⋮----
function run() public {
````
## File: script/actions/SetMaxNetworkLimit.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/SetMaxNetworkLimitBase.s.sol";
⋮----
// forge script script/actions/SetMaxNetworkLimit.s.sol:SetMaxNetworkLimitScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/SetMaxNetworkLimit.s.sol:SetMaxNetworkLimitScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract SetMaxNetworkLimitScript is SetMaxNetworkLimitBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault
⋮----
// Subnetwork Identifier (multiple subnetworks can be used, e.g., to have different max network limits for the same network)
⋮----
// Maximum amount of delegation that network is ready to receive
⋮----
function run() public {
````
## File: script/actions/SetNetworkLimit.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/SetNetworkLimitBase.s.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
// forge script script/actions/SetNetworkLimit.s.sol:SetNetworkLimitScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/SetNetworkLimit.s.sol:SetNetworkLimitScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract SetNetworkLimitScript is SetNetworkLimitBaseScript {
⋮----
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault
⋮----
// Address of the Network to set the network limit for
⋮----
// Subnetwork Identifier
⋮----
// Network limit value to set
⋮----
function run() public {
````
## File: script/actions/SetOperatorNetworkShares.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/SetOperatorNetworkSharesBase.s.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
// forge script script/actions/SetOperatorNetworkShares.s.sol:SetOperatorNetworkSharesScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/SetOperatorNetworkShares.s.sol:SetOperatorNetworkSharesScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract SetOperatorNetworkSharesScript is SetOperatorNetworkSharesBaseScript {
⋮----
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault
⋮----
// Address of the Network to set the operator network shares for
⋮----
// Subnetwork Identifier
⋮----
// Address of the Operator to set the operator network shares for
⋮----
// Operator-Network-specific shares
⋮----
function run() public {
````
## File: script/actions/SetResolver.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/SetResolverBase.s.sol";
⋮----
// forge script script/actions/SetResolver.s.sol:SetResolverScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/SetResolver.s.sol:SetResolverScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract SetResolverScript is SetResolverBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault
⋮----
// Subnetwork Identifier (multiple subnetworks can be used, e.g., to have different resolvers for the same network)
⋮----
// Address of the Resolver to set
⋮----
function run() public {
````
## File: script/actions/VetoSlash.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./base/VetoSlashBase.s.sol";
⋮----
// forge script script/actions/VetoSlash.s.sol:VetoSlashScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
// forge script script/actions/VetoSlash.s.sol:VetoSlashScript --rpc-url=RPC -—sender MULTISIG_ADDRESS —-unlocked
⋮----
contract VetoSlashScript is VetoSlashBaseScript {
// Configuration constants - UPDATE THESE BEFORE EXECUTING
⋮----
// Address of the Vault that created the slash request
⋮----
// Index of the Slash Request to veto
⋮----
function run() public {
````
## File: script/base/DeployVaultBase.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {IVault} from "../../src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IOperatorSpecificDelegator} from "../../src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IOperatorNetworkSpecificDelegator} from "../../src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "../../src/interfaces/slasher/IVetoSlasher.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Logs} from "../utils/Logs.sol";
import {SymbioticCoreConstants} from "../../test/integration/SymbioticCoreConstants.sol";
⋮----
contract DeployVaultBase is Script {
⋮----
function runBase(DeployVaultParams memory params) public returns (address, address, address) {
⋮----
function _getVaultVersion() internal virtual returns (uint64) {
⋮----
function _getVaultParamsEncoded(DeployVaultParams memory params) internal virtual returns (bytes memory) {
⋮----
function _validateOwnershipTransfer(address vault, address delegator, DeployVaultParams memory params) internal {
⋮----
// Validate vault role transfers
⋮----
// Validate delegator role transfers based on delegator type
````
## File: script/base/DeployVaultTokenizedBase.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import "./DeployVaultBase.sol";
import {IVaultTokenized} from "../../src/interfaces/vault/IVaultTokenized.sol";
⋮----
contract DeployVaultTokenizedBase is DeployVaultBase {
⋮----
function runBase(DeployVaultTokenizedParams memory params) public returns (address, address, address) {
⋮----
function _getVaultVersion() internal virtual override returns (uint64) {
⋮----
function _getVaultParamsEncoded(DeployVaultParams memory params) internal virtual override returns (bytes memory) {
````
## File: script/deploy/base/DeployCoreBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {VaultFactory} from "../../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../../src/contracts/vault/Vault.sol";
import {VaultTokenized} from "../../../src/contracts/vault/VaultTokenized.sol";
import {NetworkRestakeDelegator} from "../../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {VaultConfigurator} from "../../../src/contracts/VaultConfigurator.sol";
⋮----
contract DeployCoreBaseScript is Script {
⋮----
function run(address owner) public {
````
## File: script/deploy/base/DeployHintsBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {BaseDelegatorHints} from "../../../src/contracts/hints/DelegatorHints.sol";
import {BaseSlasherHints} from "../../../src/contracts/hints/SlasherHints.sol";
import {VaultHints} from "../../../src/contracts/hints/VaultHints.sol";
import {OptInServiceHints} from "../../../src/contracts/hints/OptInServiceHints.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
contract DeployHintsBaseScript is Script {
function run() public virtual {
````
## File: script/deploy/base/DeployMetadataServiceBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {MetadataService} from "../../../src/contracts/service/MetadataService.sol";
⋮----
contract DeployMetadataServiceBaseScript is Script {
function run(address registry) public virtual {
````
## File: script/deploy/base/DeployNetworkMiddlewareServiceBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {NetworkMiddlewareService} from "../../../src/contracts/service/NetworkMiddlewareService.sol";
⋮----
contract DeployNetworkMiddlewareServiceBaseScript is Script {
function run(address networkRegistry) public virtual {
````
## File: script/deploy/base/DeployNetworkRegistryBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {NetworkRegistry} from "../../../src/contracts/NetworkRegistry.sol";
⋮----
contract DeployNetworkRegistryBaseScript is Script {
function run() public virtual {
````
## File: script/deploy/base/DeployOperatorRegistryBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {OperatorRegistry} from "../../../src/contracts/OperatorRegistry.sol";
⋮----
contract DeployOperatorRegistryBaseScript is Script {
function run() public virtual {
````
## File: script/deploy/base/DeployOptInServiceBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {OptInService} from "../../../src/contracts/service/OptInService.sol";
⋮----
contract DeployOptInServiceBaseScript is Script {
function run(address whoRegistry, address whereRegistry, string memory name) public virtual {
````
## File: script/deploy/base/DeployVaultFactoryBase.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script} from "forge-std/Script.sol";
import {Logs} from "../../utils/Logs.sol";
⋮----
import {VaultFactory} from "../../../src/contracts/VaultFactory.sol";
⋮----
contract DeployVaultFactoryBaseScript is Script {
function run(address owner) public virtual {
````
## File: script/deploy/DeployCore.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployCoreBaseScript} from "./base/DeployCoreBase.s.sol";
⋮----
contract DeployCoreScript is DeployCoreBaseScript {
⋮----
function run() public {
````
## File: script/deploy/DeployHints.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployHintsBaseScript} from "./base/DeployHintsBase.s.sol";
⋮----
contract DeployHintsScript is DeployHintsBaseScript {
function run() public override {
````
## File: script/deploy/DeployMetadataService.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployMetadataServiceBaseScript} from "./base/DeployMetadataServiceBase.s.sol";
⋮----
contract DeployMetadataServiceScript is DeployMetadataServiceBaseScript {
⋮----
function run() public {
````
## File: script/deploy/DeployNetworkMiddlewareService.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployNetworkMiddlewareServiceBaseScript} from "./base/DeployNetworkMiddlewareServiceBase.s.sol";
⋮----
contract DeployNetworkMiddlewareServiceScript is DeployNetworkMiddlewareServiceBaseScript {
⋮----
function run() public {
````
## File: script/deploy/DeployNetworkRegistry.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployNetworkRegistryBaseScript} from "./base/DeployNetworkRegistryBase.s.sol";
⋮----
contract DeployNetworkRegistryScript is DeployNetworkRegistryBaseScript {
function run() public override {
````
## File: script/deploy/DeployOperatorRegistry.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployOperatorRegistryBaseScript} from "./base/DeployOperatorRegistryBase.s.sol";
⋮----
contract DeployOperatorRegistryScript is DeployOperatorRegistryBaseScript {
function run() public override {
````
## File: script/deploy/DeployOptInService.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployOptInServiceBaseScript} from "./base/DeployOptInServiceBase.s.sol";
⋮----
contract DeployOptInServiceScript is DeployOptInServiceBaseScript {
⋮----
function run() public {
````
## File: script/deploy/DeployVaultFactory.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {DeployVaultFactoryBaseScript} from "./base/DeployVaultFactoryBase.s.sol";
⋮----
contract DeployVaultFactoryScript is DeployVaultFactoryBaseScript {
⋮----
function run() public {
````
## File: script/integration/examples/OnboardNetwork.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "../SymbioticCoreInit.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
⋮----
import {console2} from "forge-std/Test.sol";
⋮----
// forge script script/integration/examples/OnboardNetwork.s.sol:OnboardNetworkScript SEED --sig "run(uint256)" --rpc-url=RPC --chain holesky --private-key PRIVATE_KEY --broadcast
⋮----
contract OnboardNetworkScript is SymbioticCoreInit {
⋮----
function run(uint256 seed) public override {
// ------------------------------------------------------ CONFIG ------------------------------------------------------ //
⋮----
// ------------------------------------------------------ RUN ------------------------------------------------------ //
⋮----
// ------------------------------------------------------ VERIFY ------------------------------------------------------ //
⋮----
interface IwstETH {
function stETH() external view returns (address);
function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);
function wrap(uint256 _stETHAmount) external returns (uint256);
````
## File: script/integration/SymbioticCoreBindings.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SymbioticCoreBindingsBase} from "../../test/integration/base/SymbioticCoreBindingsBase.sol";
⋮----
contract SymbioticCoreBindingsScript is SymbioticCoreBindingsBase {
modifier broadcast(address who) virtual override {
````
## File: script/integration/SymbioticCoreInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "../../test/integration/SymbioticCoreImports.sol";
⋮----
import "./SymbioticInit.sol";
import {SymbioticCoreConstants} from "../../test/integration/SymbioticCoreConstants.sol";
import {SymbioticCoreBindingsScript} from "./SymbioticCoreBindings.sol";
import {SymbioticCoreInitBase} from "../../test/integration/base/SymbioticCoreInitBase.sol";
⋮----
import {Token} from "../../test/mocks/Token.sol";
import {FeeOnTransferToken} from "../../test/mocks/FeeOnTransferToken.sol";
⋮----
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 SymbioticCoreInitBase, SymbioticInit, SymbioticCoreBindingsScript {
function run(uint256 seed) public virtual override {
⋮----
function _getStaker_SymbioticCore(address[] memory possibleTokens)
⋮----
// ------------------------------------------------------------ BROADCAST HELPERS ------------------------------------------------------------ //
⋮----
function _stopBroadcastWhenCallerModeIsSingle(Vm.CallerMode callerMode) internal virtual override {
⋮----
function _startBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode, address deployer)
⋮----
function _stopBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode) internal virtual override {
⋮----
function _startBroadcastWhenCallerModeIsRecurrent(Vm.CallerMode callerMode, address deployer)
⋮----
function _stopBroadcastWhenCallerModeIsSingleOrRecurrent(Vm.CallerMode callerMode) internal virtual override {
````
## File: script/integration/SymbioticInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SymbioticUtils} from "../../test/integration/SymbioticUtils.sol";
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {Script} from "forge-std/Script.sol";
import {Vm, VmSafe} from "forge-std/Vm.sol";
⋮----
contract SymbioticInit is SymbioticUtils, Script {
⋮----
function run(uint256 seed) public virtual {
⋮----
// ------------------------------------------------------------ GENERAL HELPERS ------------------------------------------------------------ //
⋮----
function _deal_Symbiotic(address token, address to, uint256 give) public virtual {
⋮----
function _deal_Symbiotic(address to, uint256 give) public virtual {
````
## File: script/utils/interfaces/ICreateX.sol
````
// SPDX-License-Identifier: AGPL-3.0-only
⋮----
/**
* @title CreateX Factory Interface Definition
* @author pcaversaccio (https://web.archive.org/web/20230921103111/https://pcaversaccio.com/)
* @custom:coauthor Matt Solomon (https://web.archive.org/web/20230921103335/https://mattsolomon.dev/)
*/
interface ICreateX {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* TYPES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
⋮----
/* EVENTS */
⋮----
event ContractCreation(address indexed newContract, bytes32 indexed salt);
event ContractCreation(address indexed newContract);
event Create3ProxyContractCreation(address indexed newContract, bytes32 indexed salt);
⋮----
/* CUSTOM ERRORS */
⋮----
/* CREATE */
⋮----
function deployCreate(bytes memory initCode) external payable returns (address newContract);
⋮----
function deployCreateAndInit(bytes memory initCode, bytes memory data, Values memory values, address refundAddress)
⋮----
function deployCreateAndInit(bytes memory initCode, bytes memory data, Values memory values)
⋮----
function deployCreateClone(address implementation, bytes memory data) external payable returns (address proxy);
⋮----
function computeCreateAddress(address deployer, uint256 nonce) external view returns (address computedAddress);
⋮----
function computeCreateAddress(uint256 nonce) external view returns (address computedAddress);
⋮----
/* CREATE2 */
⋮----
function deployCreate2(bytes32 salt, bytes memory initCode) external payable returns (address newContract);
⋮----
function deployCreate2(bytes memory initCode) external payable returns (address newContract);
⋮----
function deployCreate2AndInit(
⋮----
function deployCreate2AndInit(bytes32 salt, bytes memory initCode, bytes memory data, Values memory values)
⋮----
function deployCreate2AndInit(bytes memory initCode, bytes memory data, Values memory values)
⋮----
function deployCreate2Clone(bytes32 salt, address implementation, bytes memory data)
⋮----
function deployCreate2Clone(address implementation, bytes memory data) external payable returns (address proxy);
⋮----
function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer)
⋮----
function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external view returns (address computedAddress);
⋮----
/* CREATE3 */
⋮----
function deployCreate3(bytes32 salt, bytes memory initCode) external payable returns (address newContract);
⋮----
function deployCreate3(bytes memory initCode) external payable returns (address newContract);
⋮----
function deployCreate3AndInit(
⋮----
function deployCreate3AndInit(bytes32 salt, bytes memory initCode, bytes memory data, Values memory values)
⋮----
function deployCreate3AndInit(bytes memory initCode, bytes memory data, Values memory values)
⋮----
function computeCreate3Address(bytes32 salt, address deployer) external pure returns (address computedAddress);
⋮----
function computeCreate3Address(bytes32 salt) external view returns (address computedAddress);
````
## File: script/utils/interfaces/IGnosisSafe.sol
````
// SPDX-License-Identifier: LGPL-3.0-only
⋮----
/// @title Enum - Collection of enums used in Safe contracts.
/// @author Richard Meissner - @rmeissner
abstract contract Enum {
⋮----
/// @title IGnosisSafe - Gnosis Safe Interface
interface IGnosisSafe {
function addOwnerWithThreshold(address owner, uint256 _threshold) external;
function approveHash(bytes32 hashToApprove) external;
function approvedHashes(address, bytes32) external view returns (uint256);
function changeThreshold(uint256 _threshold) external;
function checkNSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures, uint256 requiredSignatures)
⋮----
function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures) external view;
function encodeTransactionData(
⋮----
function execTransaction(
⋮----
function getOwners() external view returns (address[] memory);
function getThreshold() external view returns (uint256);
function isOwner(address owner) external view returns (bool);
function nonce() external view returns (uint256);
function removeOwner(address prevOwner, address owner, uint256 _threshold) external;
function setup(
⋮----
function swapOwner(address prevOwner, address oldOwner, address newOwner) external;
````
## File: script/utils/CreateXWrapper.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ICreateX} from "./interfaces/ICreateX.sol";
⋮----
/**
* @title CreateXWrapper
* @notice Contract providing convenient wrapper functions for deployments via CreateX factory
* @dev This contract simplifies deployments by handling salt generation and factory interactions
*/
contract CreateXWrapper {
/// @notice Address of the CreateX factory contract used for CREATE3 deployments
/// @dev This is the canonical CreateX factory address deployed on multiple chains
⋮----
/**
* @notice Deploys a contract using CREATE
* @param initCode The contract bytecode to deploy
* @return The address of the deployed contract
*/
function deployCreate(bytes memory initCode) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE and calls an initialization function
* @param initCode The contract bytecode to deploy
* @param data The calldata for the initialization function call
* @return The address of the deployed and initialized contract
*/
function deployCreateAndInit(bytes memory initCode, bytes memory data) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE2
* @param initCode The contract bytecode to deploy
* @return The address of the deployed contract
*/
function deployCreate2(bytes memory initCode) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE2 with a salt
* @param salt An 11-byte salt value for deterministic address generation
* @param initCode The contract bytecode to deploy
* @return The address of the deployed contract
*/
function deployCreate2WithSalt(bytes32 salt, bytes memory initCode) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE2 and calls an initialization function
* @param salt An 32-byte salt value for deterministic address generation
* @param initCode The contract bytecode to deploy
* @param data The calldata for the initialization function call
* @return The address of the deployed and initialized contract
*/
function deployCreate2AndInit(bytes32 salt, bytes memory initCode, bytes memory data) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE3
* @param salt An 11-byte salt value for deterministic address generation
* @param code The contract bytecode to deploy
* @return The address of the deployed contract
*/
function deployCreate3(bytes32 salt, bytes memory code) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE3 with a deployer-specific salt
* @dev Combines the deployer address with the provided salt to create a unique deployment salt
* @param deployer The address of the deployer (used in salt generation)
* @param salt An 11-byte salt value for deterministic address generation
* @param code The contract bytecode to deploy
* @return The address of the deployed contract
*/
function deployCreate3WithGuardedSalt(address deployer, bytes11 salt, bytes memory code) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE3 and calls an initialization function
* @dev Combines deployment and initialization in a single transaction
* @param salt An 32-byte salt value for deterministic address generation
* @param code The contract bytecode to deploy
* @param data The calldata for the initialization function call
* @return The address of the deployed and initialized contract
*/
function deployCreate3AndInit(bytes32 salt, bytes memory code, bytes memory data) public returns (address) {
⋮----
/**
* @notice Deploys a contract using CREATE3 and calls an initialization function
* @dev Combines deployment and initialization in a single transaction
* @param deployer The address of the deployer (used in salt generation)
* @param salt An 11-byte salt value for deterministic address generation
* @param code The contract bytecode to deploy
* @param data The calldata for the initialization function call
* @return The address of the deployed and initialized contract
*/
function deployCreate3AndInitWithGuardedSalt(address deployer, bytes11 salt, bytes memory code, bytes memory data)
⋮----
/**
* @notice Computes the deterministic address for a CREATE3 deployment
* @dev Useful for predicting contract addresses before deployment
* @param salt An 32-byte salt value
* @return The computed address where the contract would be deployed
*/
function computeCreate3Address(bytes32 salt) public view returns (address) {
⋮----
/**
* @notice Computes the deterministic address for a CREATE3 deployment
* @dev Useful for predicting contract addresses before deployment
* @param salt An 11-byte salt value
* @param deployer The address of the deployer (used in salt generation)
* @return The computed address where the contract would be deployed
*/
function computeCreate3AddressWithGuardedSalt(bytes11 salt, address deployer) public view returns (address) {
⋮----
/**
* @notice Generates a 32-byte salt for CREATE3 deployment by combining deployer address and salt
* @dev The salt format is: [160-bit deployer address][8-bit zero padding][88-bit salt]
* @param salt An 11-byte (88-bit) salt value
* @param deployer The deployer's address (160-bit)
* @return A 32-byte salt suitable for CREATE3 deployment
*/
function getSaltForCreate3(bytes11 salt, address deployer) public pure returns (bytes32) {
⋮----
/**
* @notice Generates a guarded salt for CREATE3 deployment by combining deployer address and salt
* @dev The salt format is: [160-bit deployer address][8-bit zero padding][88-bit salt]
* @param deployer The deployer's address (160-bit)
* @param salt An 32-byte salt value
* @return A 32-byte salt suitable for CREATE3 deployment
*/
function getGuardedSalt(address deployer, bytes32 salt) public pure returns (bytes32) {
````
## File: script/utils/Logs.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2} from "forge-std/console2.sol";
import {Vm} from "forge-std/Vm.sol";
⋮----
import {Simulation} from "./Simulation.sol";
⋮----
function log(string memory data) public {
⋮----
function logSimulationLink(address target, bytes memory data) public {
````
## File: script/utils/ScriptBase.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Script} from "forge-std/Script.sol";
⋮----
contract ScriptBase is Script {
function sendTransaction(address target, bytes memory data) public virtual {
````
## File: script/utils/Simulation.sol
````
// SPDX-License-Identifier: MIT
⋮----
// solhint-disable no-console
import {console} from "forge-std/console.sol";
import {Vm} from "forge-std/Vm.sol";
⋮----
import {IGnosisSafe} from "./interfaces/IGnosisSafe.sol";
⋮----
/// @title Simulation
///
/// @notice Library for simulating multisig transactions with state overrides in Foundry
⋮----
/// @dev This library provides utilities for:
/// - Simulating multisig transactions before execution
/// - Overriding contract storage states for testing scenarios
/// - Generating Tenderly simulation links for external transaction analysis
/// - Managing Gnosis Safe parameters (threshold, nonce, approvals) during simulation
⋮----
/// @notice Represents state overrides for a specific contract during simulation. Used to modify contract storage
/// slots temporarily for testing purposes
⋮----
/// @dev The address of the contract whose state will be overridden
⋮----
/// @dev Array of storage slot overrides to apply to this contract
⋮----
/// @notice Represents a single storage slot override. Maps a storage slot key to a new value during simulation
⋮----
/// @dev The storage slot key
⋮----
/// @dev The new value to store in the slot during simulation
⋮----
/// @notice Contains all parameters needed to execute a simulation. Encapsulates transaction data and state
/// modifications for simulation execution
⋮----
/// @dev Address that will appear as the transaction sender
⋮----
/// @dev Target contract address for the transaction
⋮----
/// @dev Encoded transaction data to execute
⋮----
/// @dev Array of state overrides to apply before simulation
⋮----
/// @notice Foundry VM instance for state manipulation during simulations
⋮----
/// @notice Executes a simulation using the provided payload and returns state changes
⋮----
/// @dev This is the core simulation function that applies state overrides and executes the transaction
⋮----
/// @param simPayload The simulation payload containing transaction data and state overrides
⋮----
/// @return accesses Array of account access records showing all state changes during simulation
function simulateFromSimPayload(Payload memory simPayload) internal returns (Vm.AccountAccess[] memory) {
// solhint-disable-next-line max-line-length
⋮----
// Apply state overrides.
⋮----
// Execute the call in forge and return the state diff.
⋮----
/// @notice Creates a comprehensive state override for a Gnosis Safe including threshold, nonce, and approval
⋮----
/// @dev Combines multiple overrides: sets threshold to 1, updates nonce, and pre-approves transaction hash
⋮----
/// @param safe The address of the Gnosis Safe to override
/// @param nonce The nonce value to set for the safe
/// @param owner The owner address that should appear to have approved the transaction
/// @param dataHash The transaction hash that should appear as pre-approved
⋮----
/// @return state StateOverride struct containing all the necessary storage overrides
function overrideSafeThresholdApprovalAndNonce(address safe, uint256 nonce, address owner, bytes32 dataHash)
⋮----
/// @notice Creates a state override for a Gnosis Safe's threshold and nonce only
⋮----
/// @dev Sets the safe's threshold to 1 and updates its nonce for simulation purposes
⋮----
/// @param safe The address of the Gnosis Safe to override
/// @param nonce The nonce value to set for the safe
⋮----
/// @return state StateOverride struct containing threshold and nonce overrides
function overrideSafeThresholdAndNonce(address safe, uint256 nonce) internal view returns (StateOverride memory) {
⋮----
/// @notice Adds a transaction approval override to the state
⋮----
/// @dev Simulates that the specified owner has already approved the given transaction hash
⋮----
/// @param state The existing state override to modify
/// @param owner The address of the owner who should appear to have approved
/// @param dataHash The transaction hash that should appear as approved
⋮----
/// @return _ StateOverride struct with the approval override added
function addApprovalOverride(StateOverride memory state, address owner, bytes32 dataHash)
⋮----
/// @notice Adds a threshold override to set the safe's signature threshold to 1
⋮----
/// @dev Only adds the override if the current threshold is not already 1
⋮----
/// @param safe The address of the Gnosis Safe to check and potentially override
/// @param state The existing state override to modify
⋮----
/// @return _ StateOverride struct with threshold override added (if needed)
function addThresholdOverride(address safe, StateOverride memory state)
⋮----
// get the threshold and check if we need to override it
⋮----
// set the threshold (slot 4) to 1
⋮----
/// @notice Adds a nonce override to set the safe's transaction nonce
⋮----
/// @dev Only adds the override if the current nonce differs from the desired value
⋮----
/// @return _ StateOverride struct with nonce override added (if needed)
function addNonceOverride(address safe, StateOverride memory state, uint256 nonce)
⋮----
// get the nonce and check if we need to override it
⋮----
// set the nonce (slot 5) to the desired value
⋮----
/// @notice Appends a new storage override to an existing state override
⋮----
/// @dev Creates a new array with the additional override appended
⋮----
/// @param state The existing state override to extend
/// @param storageOverride The new storage override to add
⋮----
/// @return _ StateOverride struct with the new override added to the array
function addOverride(StateOverride memory state, StorageOverride memory storageOverride)
⋮----
/// @notice Generates and logs a Tenderly simulation link without state overrides
⋮----
/// @dev Convenience function that calls the full logSimulationLink with empty overrides
⋮----
/// @param to The target contract address for the simulation
/// @param data The transaction data to simulate
/// @param from The address that will appear as the transaction sender
function logSimulationLink(address to, bytes memory data, address from) internal view {
⋮----
/// @notice Generates and logs a Tenderly simulation link with state overrides
⋮----
/// @dev Creates a properly formatted URL for Tenderly's transaction simulator with state modifications
⋮----
/// @param to The target contract address for the simulation
/// @param data The transaction data to simulate
/// @param from The address that will appear as the transaction sender
/// @param overrides Array of state overrides to apply during simulation
function logSimulationLink(address to, bytes memory data, address from, StateOverride[] memory overrides)
⋮----
// the following characters are url encoded: []{}
⋮----
// tenderly's nginx has issues with long URLs, so print the raw input data separately
````
## File: script/utils/sort_errors.py
````python
#!/usr/bin/env python3
⋮----
def _error_sort_key(error_line: str) -> str
⋮----
signature = error_line.strip()[len("error ") :]
name = signature.split("(", 1)[0].strip()
⋮----
def _extract_entries(block_text: str) -> List[Tuple[int, int, str, int]]
⋮----
entries: List[Tuple[int, int, str, int]] = []
offset = 0
entry_start: Optional[int] = None
last_content_end: Optional[int] = None
current_error: Optional[str] = None
⋮----
def finalize() -> None
⋮----
entry_start = None
last_content_end = None
current_error = None
⋮----
newline_idx = block_text.find("\n", offset)
⋮----
line_end = len(block_text)
⋮----
line_end = newline_idx + 1
line = block_text[offset:line_end]
stripped = line.strip()
⋮----
last_content_end = line_end
offset = line_end
⋮----
entry_start = offset
⋮----
current_error = line.strip()
⋮----
def _sort_error_block(text: str) -> Tuple[str, bool]
⋮----
marker = "/* ERRORS */"
search_pos = 0
changed = False
⋮----
marker_idx = text.find(marker, search_pos)
⋮----
block_start = text.find("\n", marker_idx)
⋮----
cursor = block_start
first_block_idx: Optional[int] = None
last_block_idx = block_start
⋮----
newline_idx = text.find("\n", cursor)
⋮----
line_end = len(text)
⋮----
line = text[cursor:line_end]
⋮----
cursor = line_end
⋮----
first_block_idx = cursor
last_block_idx = line_end
⋮----
search_pos = cursor
⋮----
block_text = text[first_block_idx:last_block_idx]
entries = _extract_entries(block_text)
⋮----
search_pos = last_block_idx
⋮----
prefix = block_text[:entries[0][0]]
suffix = block_text[entries[-1][1]:]
sorted_entries = sorted(entries, key=lambda item: (item[2], item[3]))
sorted_chunks = [block_text[start:end].rstrip("\n") for start, end, _, _ in sorted_entries]
⋮----
new_block = prefix + "\n\n".join(sorted_chunks)
⋮----
stripped_suffix = suffix.lstrip("\n")
⋮----
text = text[:first_block_idx] + new_block + text[last_block_idx:]
changed = True
search_pos = first_block_idx + len(new_block)
⋮----
def sort_errors_in_file(path: Path)
⋮----
original = path.read_text(encoding="utf-8")
⋮----
def iter_solidity_files(targets: Iterable[Path]) -> Iterable[Path]
⋮----
def resolve_targets(path_args: Iterable[str]) -> List[Path]
⋮----
defaults = [Path(name) for name in ("src", "examples") if Path(name).exists()]
⋮----
def sort_from_stdin() -> None
⋮----
errors = sys.stdin.read()
sorted_errors = sorted(x.strip() for x in errors.splitlines())
⋮----
def main() -> int
⋮----
parser = argparse.ArgumentParser(
⋮----
args = parser.parse_args()
⋮----
targets = resolve_targets(args.paths)
````
## File: script/utils/sort_imports.py
````python
#!/usr/bin/env python3
⋮----
FROM_IMPORT_RE = re.compile(r'from\s+["\']([^"\']+)["\']', re.IGNORECASE | re.MULTILINE)
DIRECT_IMPORT_RE = re.compile(r'import\s+["\']([^"\']+)["\']', re.IGNORECASE | re.MULTILINE)
WHITESPACE_RE = re.compile(r"\s+")
⋮----
@dataclass
class ImportEntry
⋮----
start: int
end: int
text: str
path: str
order: int
⋮----
def extract_path(import_text: str) -> str
⋮----
match = FROM_IMPORT_RE.search(import_text)
⋮----
match = DIRECT_IMPORT_RE.search(import_text)
⋮----
def collect_import_entries(lines: Sequence[str]) -> List[ImportEntry]
⋮----
entries: List[ImportEntry] = []
index = 0
⋮----
stripped = lines[index].lstrip()
⋮----
start = index
statement_lines = [lines[index].rstrip()]
⋮----
end = index
text = "\n".join(statement_lines)
path = extract_path(text)
⋮----
def normalize_import_text(import_text: str) -> str
⋮----
"""Flatten whitespace so multi-line imports sort identically to single-line ones."""
compact = WHITESPACE_RE.sub(" ", import_text.strip())
compact = compact.replace("{ ", "{").replace(" }", "}")
compact = compact.replace("( ", "(").replace(" )", ")")
⋮----
def classify_import(path: str) -> str
⋮----
normalized = path.lstrip("./")
lower = normalized.lower()
⋮----
library = normalized.split("/", 1)[0]
⋮----
def build_sorted_block(entries: Sequence[ImportEntry]) -> List[str]
⋮----
grouped: Dict[str, List[ImportEntry]] = defaultdict(list)
⋮----
ordered_groups: List[List[ImportEntry]] = []
⋮----
external_groups = sorted(
⋮----
block_text = "\n\n".join("\n".join(entry.text for entry in group) for group in ordered_groups)
⋮----
def sort_imports_in_file(path: Path) -> None
⋮----
original_text = path.read_text(encoding="utf-8")
has_trailing_newline = original_text.endswith("\n")
lines = original_text.splitlines()
⋮----
entries = collect_import_entries(lines)
⋮----
block_start = entries[0].start
block_end = entries[-1].end
covered_indexes = set()
⋮----
new_block_lines = build_sorted_block(entries)
new_lines = lines[:block_start] + new_block_lines + lines[block_end + 1 :]
new_text = "\n".join(new_lines)
⋮----
def iter_solidity_files(targets: Iterable[Path]) -> Iterable[Path]
⋮----
def resolve_targets(path_args: Iterable[str]) -> List[Path]
⋮----
defaults = [Path(name) for name in ("src", "examples") if Path(name).exists()]
⋮----
def main() -> int
⋮----
parser = argparse.ArgumentParser(
⋮----
args = parser.parse_args()
⋮----
targets = resolve_targets(args.paths)
````
## File: script/DeployVault.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import "./base/DeployVaultBase.sol";
⋮----
// forge script script/DeployVault.s.sol:DeployVaultScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
⋮----
contract DeployVaultScript is DeployVaultBase {
// Configurations - UPDATE THESE BEFORE DEPLOYMENT
⋮----
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
⋮----
// Address of the collateral token
⋮----
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
⋮----
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
⋮----
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
⋮----
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
⋮----
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
⋮----
// Whether to deploy a slasher
⋮----
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
⋮----
// Duration of a veto period (should be less than EPOCH_DURATION)
⋮----
// Optional
⋮----
// Deposit limit (maximum amount of the active stake allowed in the vault)
⋮----
// Addresses of the whitelisted depositors
⋮----
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
⋮----
// Delay in epochs for a network to update a resolver
⋮----
function run() public {
````
## File: script/DeployVaultTokenized.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import "./base/DeployVaultTokenizedBase.sol";
⋮----
// forge script script/DeployVaultTokenized.s.sol:DeployVaultTokenizedScript --rpc-url=RPC --private-key PRIVATE_KEY --broadcast
⋮----
contract DeployVaultTokenizedScript is DeployVaultTokenizedBase {
// Configurations - UPDATE THESE BEFORE DEPLOYMENT
⋮----
// Name of the ERC20 representing shares of the active stake in the vault
⋮----
// Symbol of the ERC20 representing shares of the active stake in the vault
⋮----
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
⋮----
// Address of the collateral token
⋮----
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
⋮----
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
⋮----
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
⋮----
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
⋮----
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
⋮----
// Whether to deploy a slasher
⋮----
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
⋮----
// Duration of a veto period (should be less than EPOCH_DURATION)
⋮----
// Optional
⋮----
// Deposit limit (maximum amount of the active stake allowed in the vault)
⋮----
// Addresses of the whitelisted depositors
⋮----
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
⋮----
// Delay in epochs for a network to update a resolver
⋮----
function run() public {
````
## File: snapshots/gas.txt
````
No files changed, compilation skipped
Ran 1 test for test/common/MigratableEntityProxy.t.sol:MigratableEntityProxyTest
[PASS] test_MigrateRevertProxyDeniedAdminAccess() (gas: 1590363)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.34ms (124.79µs CPU time)
Ran 3 tests for test/NetworkRegistry.t.sol:NetworkRegistryTest
[PASS] test_Create() (gas: 30385)
[PASS] test_Register() (gas: 121217)
[PASS] test_RegisterRevertEntityAlreadyRegistered() (gas: 143570)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 7.46ms (1.27ms CPU time)
Ran 1 test for test/common/Entity.t.sol:EntityTest
[PASS] test_Create() (gas: 1055982)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.53ms (322.96µs CPU time)
Ran 7 tests for test/common/Factory.t.sol:FactoryTest
[PASS] test_BlacklistRevertAlreadyBlacklisted() (gas: 438847)
[PASS] test_BlacklistRevertIinvalidType() (gas: 34346)
[PASS] test_Create() (gas: 955167)
[PASS] test_CreateRevertInvalidIndex() (gas: 745962)
[PASS] test_WhitelistRevertAlreadyWhitelisted() (gas: 366082)
[PASS] test_WhitelistRevertInvalidImplementation1() (gas: 291539)
[PASS] test_WhitelistRevertInvalidImplementation2() (gas: 646932)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 8.39ms (1.15ms CPU time)
Ran 1 test for test/DelegatorFactory.t.sol:DelegatorFactoryTest
[PASS] test_Create() (gas: 1601250)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 8.84ms (275.50µs CPU time)
Ran 1 test for test/SlasherFactory.t.sol:SlasherFactoryTest
[PASS] test_Create() (gas: 1451521)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.52ms (257.79µs CPU time)
Ran 12 tests for test/service/OptInService.t.sol:OperatorOptInServiceTest
[PASS] test_Create() (gas: 669669)
[PASS] test_IncreaseNonce() (gas: 322937)
[PASS] test_OptInRevertAlreadyOptedIn() (gas: 364757)
[PASS] test_OptInRevertNotEntity() (gas: 157162)
[PASS] test_OptInRevertNotWhereEntity() (gas: 162173)
[PASS] test_OptInWithExpiredDeadline() (gas: 258583)
[PASS] test_OptInWithInvalidSignature() (gas: 268481)
[PASS] test_OptInWithSignature() (gas: 353418)
[PASS] test_OptOutRevertNotOptedIn() (gas: 246774)
[PASS] test_OptOutWithExpiredDeadline() (gas: 363819)
[PASS] test_OptOutWithInvalidSignature() (gas: 373774)
[PASS] test_OptOutWithSignature() (gas: 416417)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 6.78ms (6.52ms CPU time)
Ran 1 test for test/POC.t.sol:POCTest
[PASS] test_POC() (gas: 463)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.22ms (17.29µs CPU time)
Ran 1 test for test/common/Registry.t.sol:FactoryTest
[PASS] test_Create() (gas: 245091)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 790.92µs (307.88µs CPU time)
Ran 10 tests for test/common/MigratablesFactory.t.sol:MigratablesFactoryTest
[PASS] test_BlacklistRevertAlreadyBlacklisted() (gas: 642958)
[PASS] test_BlacklistRevertInvalidVersion() (gas: 32421)
[PASS] test_Create() (gas: 2194685)
[PASS] test_CreateRevertInvalidVersion() (gas: 648291)
[PASS] test_Migrate(uint256) (runs: 1000, μ: 2207559, ~: 2207710)
[PASS] test_MigrateRevertImproperOwner() (gas: 1613358)
[PASS] test_MigrateRevertInvalidVersion() (gas: 1617082)
[PASS] test_MigrateRevertOldVersion() (gas: 1607001)
[PASS] test_WhitelistRevertAlreadyWhitelisted() (gas: 594326)
[PASS] test_WhitelistRevertInvalidImplementation() (gas: 495950)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 166.26ms (159.38ms CPU time)
Ran 3 tests for test/service/NetworkMiddlewareService.t.sol:MiddlewareServiceTest
[PASS] test_Create(address) (runs: 1000, μ: 193163, ~: 193243)
[PASS] test_SetMiddlewareRevertAlreadySet(address) (runs: 1000, μ: 206717, ~: 206879)
[PASS] test_SetMiddlewareRevertNotNetwork(address) (runs: 1000, μ: 59304, ~: 59381)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 170.52ms (163.97ms CPU time)
Ran 3 tests for test/service/MetadataService.t.sol:MetadataServiceTest
[PASS] test_Create(string) (runs: 1000, μ: 225049, ~: 223593)
[PASS] test_SetMetadataURLRevertAlreadySet(string) (runs: 1000, μ: 236201, ~: 211163)
[PASS] test_SetMetadataURLRevertNotEntity(string) (runs: 1000, μ: 60607, ~: 60522)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 233.95ms (227.35ms CPU time)
Ran 4 tests for test/common/MigratableEntity.t.sol:MigratableEntityTest
[PASS] test_Create() (gas: 993840)
[PASS] test_Migrate(uint256,uint256,uint256,uint256) (runs: 1000, μ: 2366075, ~: 2366290)
[PASS] test_MigrateRevertNotFactory() (gas: 1605760)
[PASS] test_ReinitRevertAlreadyInitialized() (gas: 1548291)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 237.82ms (230.87ms CPU time)
Ran 3 tests for test/OperatorRegistry.t.sol:OperatorRegistryTest
[PASS] test_Create() (gas: 30385)
[PASS] test_Register() (gas: 121195)
[PASS] test_RegisterRevertEntityAlreadyRegistered() (gas: 143526)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 287.00µs (151.29µs CPU time)
Ran 1 test for test/VaultConfigurator.t.sol:VaultConfiguratorTest
[PASS] test_Create(address,address,uint48,bool,bool,uint256,bool,address) (runs: 1000, μ: 1385813, ~: 1495052)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 351.41ms (350.13ms CPU time)
Ran 1 test for test/VaultFactory.t.sol:VaultFactoryTest
[PASS] test_Create() (gas: 973737)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.51ms (188.46µs CPU time)
Ran 9 tests for test/integration/actions/ActionScripts.t.sol:ActionScriptsTest
[PASS] test_OptInNetwork() (gas: 823352)
[PASS] test_OptInVault() (gas: 822391)
[PASS] test_RegisterOperator() (gas: 727520)
[PASS] test_SetHook() (gas: 608825)
[PASS] test_SetMaxNetworkLimit() (gas: 652573)
[PASS] test_SetNetworkLimit() (gas: 803051)
[PASS] test_SetOperatorNetworkShares() (gas: 939148)
[PASS] test_SetResolver() (gas: 688144)
[PASS] test_VetoSlash() (gas: 3122811)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 2.64s (9.47ms CPU time)
Ran 3 tests for test/integration/SymbioticCoreIntegrationExample.t.sol:SymbioticCoreIntegrationExample
[PASS] test_Network() (gas: 22541060)
[PASS] test_NetworkAdvanced() (gas: 171805965)
[PASS] test_Simple() (gas: 1995899)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 5.76s (191.99ms CPU time)
Ran 19 tests for test/delegator/OperatorSpecificDelegator.t.sol:OperatorSpecificDelegatorTest
[PASS] test_Create(uint48) (runs: 1000, μ: 1213812, ~: 1213732)
[PASS] test_CreateRevertDuplicateRoleHolder1(uint48) (runs: 1000, μ: 1358313, ~: 1358228)
[PASS] test_CreateRevertMissingRoleHolders(uint48) (runs: 1000, μ: 1323932, ~: 1323855)
[PASS] test_CreateRevertNotOperator(uint48) (runs: 1000, μ: 1330516, ~: 1330430)
[PASS] test_CreateRevertNotVault(uint48) (runs: 1000, μ: 1280493, ~: 1280410)
[PASS] test_CreateRevertZeroAddressRoleHolder1(uint48) (runs: 1000, μ: 1329908, ~: 1329821)
[PASS] test_OnSlashRevertNotSlasher(uint48) (runs: 1000, μ: 1166015, ~: 1165931)
[PASS] test_SetHook(uint48) (runs: 1000, μ: 1624330, ~: 1624229)
[PASS] test_SetHookRevertAlreadySet(uint48) (runs: 1000, μ: 1402991, ~: 1402887)
[PASS] test_SetMaxNetworkLimit(uint48,uint256,uint256,uint256) (runs: 1000, μ: 1740596, ~: 1741482)
[PASS] test_SetMaxNetworkLimitRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1368117, ~: 1368059)
[PASS] test_SetMaxNetworkLimitRevertNotNetwork(uint48,uint256) (runs: 1000, μ: 1310499, ~: 1310488)
[PASS] test_SetNetworkLimit(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 1925252, ~: 1925717)
[PASS] test_SetNetworkLimitRevertAlreadySet(uint48,uint256,uint256) (runs: 1000, μ: 1496571, ~: 1496507)
[PASS] test_SetNetworkLimitRevertExceedsMaxNetworkLimit(uint48,uint256,uint256) (runs: 1000, μ: 1361848, ~: 1361854)
[PASS] test_SlashBase(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3380949, ~: 3390108)
[PASS] test_SlashWithHook(uint256,uint256,uint256) (runs: 1000, μ: 3234973, ~: 3227738)
[PASS] test_SlashWithHookGas(uint256,uint256,uint256) (runs: 1000, μ: 3256728, ~: 3146920)
[PASS] test_Stakes(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3258963, ~: 3260033)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 10.05s (9.02s CPU time)
Ran 22 tests for test/delegator/NetworkRestakeDelegator.t.sol:NetworkRestakeDelegatorTest
[PASS] test_Create(uint48) (runs: 1000, μ: 1122749, ~: 1122670)
[PASS] test_CreateRevertDuplicateRoleHolder1(uint48) (runs: 1000, μ: 1253109, ~: 1253028)
[PASS] test_CreateRevertDuplicateRoleHolder2(uint48) (runs: 1000, μ: 1278329, ~: 1278242)
[PASS] test_CreateRevertMissingRoleHolders(uint48) (runs: 1000, μ: 1226231, ~: 1226147)
[PASS] test_CreateRevertNotVault(uint48) (runs: 1000, μ: 1180290, ~: 1180203)
[PASS] test_CreateRevertZeroAddressRoleHolder1(uint48) (runs: 1000, μ: 1226808, ~: 1226722)
[PASS] test_CreateRevertZeroAddressRoleHolder2(uint48) (runs: 1000, μ: 1252024, ~: 1251936)
[PASS] test_OnSlashRevertNotSlasher(uint48) (runs: 1000, μ: 1067086, ~: 1067002)
[PASS] test_SetHook(uint48) (runs: 1000, μ: 1779195, ~: 1779098)
[PASS] test_SetHookRevertAlreadySet(uint48) (runs: 1000, μ: 1430864, ~: 1430773)
[PASS] test_SetMaxNetworkLimit(uint48,uint256,uint256,uint256) (runs: 1000, μ: 1644681, ~: 1645449)
[PASS] test_SetMaxNetworkLimitRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1269177, ~: 1269140)
[PASS] test_SetMaxNetworkLimitRevertNotNetwork(uint48,uint256) (runs: 1000, μ: 1211559, ~: 1211548)
[PASS] test_SetNetworkLimit(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 1829266, ~: 1829878)
[PASS] test_SetNetworkLimitRevertAlreadySet(uint48,uint256,uint256) (runs: 1000, μ: 1397642, ~: 1397578)
[PASS] test_SetNetworkLimitRevertExceedsMaxNetworkLimit(uint48,uint256,uint256) (runs: 1000, μ: 1265355, ~: 1265327)
[PASS] test_SetOperatorNetworkSharesBoth(uint48,uint256,uint256,uint256) (runs: 1000, μ: 3293352, ~: 3294486)
[PASS] test_SetOperatorNetworkSharesRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1529697, ~: 1529636)
[PASS] test_SlashBase(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 4188710, ~: 4188130)
[PASS] test_SlashWithHookBase(uint256,uint256,uint256,uint256) (runs: 1000, μ: 4240016, ~: 4233565)
[PASS] test_SlashWithHookGas(uint256,uint256,uint256,uint256) (runs: 1000, μ: 4205019, ~: 4046883)
[PASS] test_Stakes(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 4590721, ~: 4579970)
Suite result: ok. 22 passed; 0 failed; 0 skipped; finished in 10.87s (12.89s CPU time)
Ran 56 tests for test/vault/VaultTokenized.t.sol:VaultTokenizedTest
[PASS] test_Claim(uint256,uint256) (runs: 1000, μ: 1939059, ~: 1939300)
[PASS] test_ClaimBatch(uint256,uint256,uint256) (runs: 1000, μ: 2275813, ~: 2275840)
[PASS] test_ClaimBatchRevertAlreadyClaimed(uint256,uint256,uint256) (runs: 1000, μ: 2169808, ~: 2169841)
[PASS] test_ClaimBatchRevertInsufficientClaim(uint256,uint256,uint256) (runs: 1000, μ: 2178797, ~: 2178841)
[PASS] test_ClaimBatchRevertInvalidEpoch(uint256,uint256,uint256) (runs: 1000, μ: 2169731, ~: 2169765)
[PASS] test_ClaimBatchRevertInvalidLengthEpochs(uint256,uint256,uint256) (runs: 1000, μ: 2113469, ~: 2113572)
[PASS] test_ClaimBatchRevertInvalidRecipient(uint256,uint256,uint256) (runs: 1000, μ: 2136841, ~: 2136865)
[PASS] test_ClaimRevertAlreadyClaimed(uint256,uint256) (runs: 1000, μ: 1936992, ~: 1937433)
[PASS] test_ClaimRevertInsufficientClaim(uint256,uint256) (runs: 1000, μ: 1846341, ~: 1846555)
[PASS] test_ClaimRevertInvalidEpoch(uint256,uint256) (runs: 1000, μ: 1836812, ~: 1836902)
[PASS] test_ClaimRevertInvalidRecipient(uint256,uint256) (runs: 1000, μ: 1831471, ~: 1831739)
[PASS] test_Create2(address,uint48,bool,bool,uint256) (runs: 1000, μ: 1767940, ~: 1768071)
[PASS] test_CreateRevertInvalidCollateral(uint48) (runs: 1000, μ: 207873, ~: 207785)
[PASS] test_CreateRevertInvalidEpochDuration() (gas: 207079)
[PASS] test_CreateRevertMissingRoles1(uint48) (runs: 1000, μ: 196070, ~: 195986)
[PASS] test_CreateRevertMissingRoles2(uint48) (runs: 1000, μ: 194792, ~: 194696)
[PASS] test_CreateRevertMissingRoles3(uint48) (runs: 1000, μ: 195024, ~: 194934)
[PASS] test_CreateRevertMissingRoles4(uint48) (runs: 1000, μ: 195974, ~: 195884)
[PASS] test_CreateRevertMissingRoles5(uint48) (runs: 1000, μ: 196109, ~: 196019)
[PASS] test_DepositBoth(uint256,uint256) (runs: 1000, μ: 2443055, ~: 2443071)
[PASS] test_DepositRevertInsufficientDeposit() (gas: 1098207)
[PASS] test_DepositRevertInvalidOnBehalfOf(uint256) (runs: 1000, μ: 1084655, ~: 1084554)
[PASS] test_DepositTwice(uint256,uint256) (runs: 1000, μ: 2962366, ~: 2962385)
[PASS] test_DepositTwiceFeeOnTransferCollateral(uint256,uint256) (runs: 1000, μ: 2933528, ~: 2933557)
[PASS] test_OnSlashRevertNotSlasher() (gas: 1083521)
[PASS] test_RedeemRevertInsufficientRedeemption(uint256) (runs: 1000, μ: 1546322, ~: 1546227)
[PASS] test_RedeemRevertInvalidClaimer(uint256) (runs: 1000, μ: 1520659, ~: 1520534)
[PASS] test_RedeemRevertTooMuchRedeem(uint256) (runs: 1000, μ: 1528984, ~: 1528881)
[PASS] test_RedeemTwice(uint256,uint256,uint256) (runs: 1000, μ: 3184141, ~: 3184191)
[PASS] test_SetDelegator() (gas: 1133694)
[PASS] test_SetDelegatorRevertDelegatorAlreadyInitialized() (gas: 1129038)
[PASS] test_SetDelegatorRevertInvalidDelegator() (gas: 1704353)
[PASS] test_SetDelegatorRevertNotDelegator() (gas: 719177)
[PASS] test_SetDepositLimit(uint256,uint256,uint256) (runs: 1000, μ: 1776846, ~: 1776780)
[PASS] test_SetDepositLimitRevertAlreadySet(uint256) (runs: 1000, μ: 1281584, ~: 1281454)
[PASS] test_SetDepositLimitRevertDepositLimitReached(uint256,uint256) (runs: 1000, μ: 1868979, ~: 1869027)
[PASS] test_SetDepositLimitToNull(uint256) (runs: 1000, μ: 1314173, ~: 1314114)
[PASS] test_SetDepositWhitelist() (gas: 1191806)
[PASS] test_SetDepositWhitelistRevertAlreadySet() (gas: 1170520)
[PASS] test_SetDepositWhitelistRevertNotWhitelistedDepositor() (gas: 1606707)
[PASS] test_SetDepositorWhitelistStatus() (gas: 1909834)
[PASS] test_SetDepositorWhitelistStatusRevertAlreadySet() (gas: 1277528)
[PASS] test_SetDepositorWhitelistStatusRevertInvalidAccount() (gas: 1216701)
[PASS] test_SetIsDepositLimit() (gas: 1191334)
[PASS] test_SetIsDepositLimitRevertAlreadySet() (gas: 1169663)
[PASS] test_SetSlasher() (gas: 1033194)
[PASS] test_SetSlasherRevertInvalidSlasher() (gas: 1609359)
[PASS] test_SetSlasherRevertNotSlasher() (gas: 974292)
[PASS] test_SetSlasherRevertSlasherAlreadyInitialized() (gas: 1033576)
[PASS] test_SetSlasherZeroAddress() (gas: 727045)
[PASS] test_Slash(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 4348925, ~: 4353012)
[PASS] test_Transfer(uint256,uint256) (runs: 1000, μ: 1785801, ~: 1599573)
[PASS] test_WithdrawRevertInsufficientWithdrawal(uint256) (runs: 1000, μ: 1521060, ~: 1520943)
[PASS] test_WithdrawRevertInvalidClaimer(uint256) (runs: 1000, μ: 1521120, ~: 1520993)
[PASS] test_WithdrawRevertTooMuchWithdraw(uint256) (runs: 1000, μ: 1548563, ~: 1548479)
[PASS] test_WithdrawTwice(uint256,uint256,uint256) (runs: 1000, μ: 3241438, ~: 3241459)
Suite result: ok. 56 passed; 0 failed; 0 skipped; finished in 11.08s (18.83s CPU time)
Ran 55 tests for test/vault/Vault.t.sol:VaultTest
[PASS] test_Claim(uint256,uint256) (runs: 1000, μ: 1883063, ~: 1883293)
[PASS] test_ClaimBatch(uint256,uint256,uint256) (runs: 1000, μ: 2217591, ~: 2217704)
[PASS] test_ClaimBatchRevertAlreadyClaimed(uint256,uint256,uint256) (runs: 1000, μ: 2111920, ~: 2112014)
[PASS] test_ClaimBatchRevertInsufficientClaim(uint256,uint256,uint256) (runs: 1000, μ: 2120966, ~: 2121015)
[PASS] test_ClaimBatchRevertInvalidEpoch(uint256,uint256,uint256) (runs: 1000, μ: 2111822, ~: 2111920)
[PASS] test_ClaimBatchRevertInvalidLengthEpochs(uint256,uint256,uint256) (runs: 1000, μ: 2055910, ~: 2055952)
[PASS] test_ClaimBatchRevertInvalidRecipient(uint256,uint256,uint256) (runs: 1000, μ: 2079011, ~: 2079045)
[PASS] test_ClaimRevertAlreadyClaimed(uint256,uint256) (runs: 1000, μ: 1881380, ~: 1881548)
[PASS] test_ClaimRevertInsufficientClaim(uint256,uint256) (runs: 1000, μ: 1790376, ~: 1790812)
[PASS] test_ClaimRevertInvalidEpoch(uint256,uint256) (runs: 1000, μ: 1780964, ~: 1781181)
[PASS] test_ClaimRevertInvalidRecipient(uint256,uint256) (runs: 1000, μ: 1775869, ~: 1776018)
[PASS] test_Create2(address,uint48,bool,bool,uint256) (runs: 1000, μ: 1637667, ~: 1637956)
[PASS] test_CreateRevertInvalidCollateral(uint48) (runs: 1000, μ: 202129, ~: 202042)
[PASS] test_CreateRevertInvalidEpochDuration() (gas: 201337)
[PASS] test_CreateRevertMissingRoles1(uint48) (runs: 1000, μ: 190424, ~: 190336)
[PASS] test_CreateRevertMissingRoles2(uint48) (runs: 1000, μ: 189156, ~: 189068)
[PASS] test_CreateRevertMissingRoles3(uint48) (runs: 1000, μ: 189389, ~: 189306)
[PASS] test_CreateRevertMissingRoles4(uint48) (runs: 1000, μ: 190323, ~: 190234)
[PASS] test_CreateRevertMissingRoles5(uint48) (runs: 1000, μ: 190448, ~: 190369)
[PASS] test_DepositBoth(uint256,uint256) (runs: 1000, μ: 2319070, ~: 2319089)
[PASS] test_DepositRevertInsufficientDeposit() (gas: 1046630)
[PASS] test_DepositRevertInvalidOnBehalfOf(uint256) (runs: 1000, μ: 1033052, ~: 1032954)
[PASS] test_DepositTwice(uint256,uint256) (runs: 1000, μ: 2841858, ~: 2841888)
[PASS] test_DepositTwiceFeeOnTransferCollateral(uint256,uint256) (runs: 1000, μ: 2872125, ~: 2872161)
[PASS] test_OnSlashRevertNotSlasher() (gas: 1031922)
[PASS] test_RedeemRevertInsufficientRedeemption(uint256) (runs: 1000, μ: 1492863, ~: 1492717)
[PASS] test_RedeemRevertInvalidClaimer(uint256) (runs: 1000, μ: 1467207, ~: 1467122)
[PASS] test_RedeemRevertTooMuchRedeem(uint256) (runs: 1000, μ: 1475546, ~: 1475419)
[PASS] test_RedeemTwice(uint256,uint256,uint256) (runs: 1000, μ: 3116831, ~: 3116922)
[PASS] test_SetDelegator() (gas: 1081968)
[PASS] test_SetDelegatorRevertDelegatorAlreadyInitialized() (gas: 1077705)
[PASS] test_SetDelegatorRevertInvalidDelegator() (gas: 1602079)
[PASS] test_SetDelegatorRevertNotDelegator() (gas: 667955)
[PASS] test_SetDepositLimit(uint256,uint256,uint256) (runs: 1000, μ: 1722045, ~: 1721958)
[PASS] test_SetDepositLimitRevertAlreadySet(uint256) (runs: 1000, μ: 1229260, ~: 1229118)
[PASS] test_SetDepositLimitRevertDepositLimitReached(uint256,uint256) (runs: 1000, μ: 1814851, ~: 1814897)
[PASS] test_SetDepositLimitToNull(uint256) (runs: 1000, μ: 1261563, ~: 1261491)
[PASS] test_SetDepositWhitelist() (gas: 1139613)
[PASS] test_SetDepositWhitelistRevertAlreadySet() (gas: 1118569)
[PASS] test_SetDepositWhitelistRevertNotWhitelistedDepositor() (gas: 1552852)
[PASS] test_SetDepositorWhitelistStatus() (gas: 1853613)
[PASS] test_SetDepositorWhitelistStatusRevertAlreadySet() (gas: 1225203)
[PASS] test_SetDepositorWhitelistStatusRevertInvalidAccount() (gas: 1164552)
[PASS] test_SetIsDepositLimit() (gas: 1139207)
[PASS] test_SetIsDepositLimitRevertAlreadySet() (gas: 1117844)
[PASS] test_SetSlasher() (gas: 981347)
[PASS] test_SetSlasherRevertInvalidSlasher() (gas: 1506918)
[PASS] test_SetSlasherRevertNotSlasher() (gas: 922923)
[PASS] test_SetSlasherRevertSlasherAlreadyInitialized() (gas: 982053)
[PASS] test_SetSlasherZeroAddress() (gas: 675779)
[PASS] test_Slash(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 4285558, ~: 4289457)
[PASS] test_WithdrawRevertInsufficientWithdrawal(uint256) (runs: 1000, μ: 1467493, ~: 1467409)
[PASS] test_WithdrawRevertInvalidClaimer(uint256) (runs: 1000, μ: 1467552, ~: 1467471)
[PASS] test_WithdrawRevertTooMuchWithdraw(uint256) (runs: 1000, μ: 1494997, ~: 1494909)
[PASS] test_WithdrawTwice(uint256,uint256,uint256) (runs: 1000, μ: 3119108, ~: 3119142)
Suite result: ok. 55 passed; 0 failed; 0 skipped; finished in 10.39s (16.54s CPU time)
Ran 15 tests for test/delegator/OperatorNetworkSpecificDelegator.t.sol:OperatorNetworkSpecificDelegatorTest
[PASS] test_Create(uint48) (runs: 1000, μ: 1353344, ~: 1353258)
[PASS] test_CreateRevertNotNetwork(uint48) (runs: 1000, μ: 1484301, ~: 1484216)
[PASS] test_CreateRevertNotOperator(uint48) (runs: 1000, μ: 1490203, ~: 1490122)
[PASS] test_CreateRevertNotVault(uint48) (runs: 1000, μ: 1433457, ~: 1433373)
[PASS] test_OnSlashRevertNotSlasher(uint48) (runs: 1000, μ: 1322009, ~: 1321918)
[PASS] test_SetHook(uint48) (runs: 1000, μ: 1730775, ~: 1730676)
[PASS] test_SetHookRevertAlreadySet(uint48) (runs: 1000, μ: 1533305, ~: 1533203)
[PASS] test_SetMaxNetworkLimit(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 1878633, ~: 1879084)
[PASS] test_SetMaxNetworkLimitRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1465836, ~: 1465781)
[PASS] test_SetMaxNetworkLimitRevertInvalidNetwork(uint48,uint256) (runs: 1000, μ: 1621707, ~: 1621659)
[PASS] test_SetMaxNetworkLimitRevertNotNetwork(uint48,uint256) (runs: 1000, μ: 1313492, ~: 1313472)
[PASS] test_SlashBase(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3341335, ~: 3349312)
[PASS] test_SlashWithHook(uint256,uint256,uint256) (runs: 1000, μ: 3125003, ~: 3117530)
[PASS] test_SlashWithHookGas(uint256,uint256,uint256) (runs: 1000, μ: 2969808, ~: 2957022)
[PASS] test_Stakes(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3330543, ~: 3331601)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 13.55s (7.66s CPU time)
Ran 12 tests for test/slasher/Slasher.t.sol:SlasherTest
[PASS] test_Create(uint48) (runs: 1000, μ: 1324841, ~: 1324753)
[PASS] test_CreateRevertNoBurner(uint48) (runs: 1000, μ: 1249743, ~: 1249654)
[PASS] test_CreateRevertNotVault(uint48) (runs: 1000, μ: 1171609, ~: 1171527)
[PASS] test_Slash(uint48,uint256,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 5870003, ~: 5880941)
[PASS] test_SlashRevertInsufficientSlash1(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3253005, ~: 3262381)
[PASS] test_SlashRevertInsufficientSlash2(uint48,uint256,uint256,uint256,uint256,bool) (runs: 1000, μ: 2472932, ~: 2472900)
[PASS] test_SlashRevertInvalidCaptureTimestamp(uint48,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2504348, ~: 2504139)
[PASS] test_SlashRevertNotNetworkMiddleware(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2584541, ~: 2584486)
[PASS] test_SlashSubnetworks(uint48,uint256,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 9559201, ~: 9589173)
[PASS] test_SlashWithBurner(uint256,uint256,uint256,uint256) (runs: 1000, μ: 3182541, ~: 3182538)
[PASS] test_SlashWithBurnerDisabled(uint256,uint256,uint256,uint256) (runs: 1000, μ: 3111808, ~: 3111733)
[PASS] test_SlashWithBurnerGas(uint256,uint256,uint256,uint256) (runs: 1001, μ: 3297094, ~: 3378552)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 23.03s (34.80s CPU time)
Ran 30 tests for test/slasher/VetoSlasher.t.sol:VetoSlasherTest
[PASS] test_Create(uint48,uint48) (runs: 1000, μ: 1385741, ~: 1386864)
[PASS] test_CreateRevertInvalidResolverSetEpochsDelay(uint48,uint48,uint256) (runs: 1000, μ: 1233496, ~: 1233405)
[PASS] test_CreateRevertInvalidVetoDuration(uint48,uint48,uint256) (runs: 1000, μ: 1233470, ~: 1233422)
[PASS] test_CreateRevertNotVault(uint48,uint48,uint256) (runs: 1000, μ: 1177381, ~: 1177415)
[PASS] test_ExecuteSlash1(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3957819, ~: 3962802)
[PASS] test_ExecuteSlash2(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3845720, ~: 3848658)
[PASS] test_ExecuteSlashRevertInsufficientSlash1(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3144374, ~: 3156348)
[PASS] test_ExecuteSlashRevertInsufficientSlash2(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3375962, ~: 3387121)
[PASS] test_ExecuteSlashRevertNotNetworkMiddleware(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2781551, ~: 2782714)
[PASS] test_ExecuteSlashRevertSlashPeriodEnded(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2797023, ~: 2798115)
[PASS] test_ExecuteSlashRevertSlashRequestCompleted(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3242405, ~: 3243351)
[PASS] test_ExecuteSlashRevertSlashRequestNotExist(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2772340, ~: 2773747)
[PASS] test_ExecuteSlashRevertVetoPeriodNotEnded(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2870623, ~: 2870614)
[PASS] test_ExecuteSlashWithoutResolver1(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3189883, ~: 3202188)
[PASS] test_ExecuteSlashWithoutResolver2(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3356636, ~: 3369150)
[PASS] test_RequestSlash(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3414388, ~: 3414963)
[PASS] test_RequestSlashRevertInsufficientSlash(uint48,uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3171394, ~: 3173566)
[PASS] test_RequestSlashRevertInvalidCaptureTimestamp(uint48,uint48,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2557521, ~: 2557676)
[PASS] test_RequestSlashRevertNotNetworkMiddleware(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2949272, ~: 2950162)
[PASS] test_SetResolver(uint48,uint48,address,address) (runs: 1000, μ: 2073091, ~: 2074643)
[PASS] test_SetResolverRevertAlreadySet1(uint48,uint48) (runs: 1000, μ: 1482518, ~: 1483997)
[PASS] test_SetResolverRevertAlreadySet2(uint48,uint48) (runs: 1000, μ: 1567303, ~: 1568520)
[PASS] test_SetResolverRevertNotNetwork(uint48,uint48) (runs: 1000, μ: 1479277, ~: 1480973)
[PASS] test_VetoSlash(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2966891, ~: 2966785)
[PASS] test_VetoSlashRevertNoResolver1(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2780293, ~: 2780210)
[PASS] test_VetoSlashRevertNoResolver2(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2947345, ~: 2947204)
[PASS] test_VetoSlashRevertNotResolver(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2865183, ~: 2865071)
[PASS] test_VetoSlashRevertSlashRequestCompleted(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2909813, ~: 2909699)
[PASS] test_VetoSlashRevertSlashRequestNotExist(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2854105, ~: 2854019)
[PASS] test_VetoSlashRevertVetoPeriodEnded(uint48,uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 2866480, ~: 2866319)
Suite result: ok. 30 passed; 0 failed; 0 skipped; finished in 17.28s (30.76s CPU time)
Ran 10 tests for test/libraries/Checkpoints.t.sol:CheckpointsTrace256Test
[PASS] testAt(uint48[],uint256[],uint32) (runs: 1000, μ: 8487700, ~: 8970900)
[PASS] testLatest(uint48[],uint256[]) (runs: 1000, μ: 8390004, ~: 8790696)
[PASS] testLatestCheckpoint(uint48[],uint256[]) (runs: 1000, μ: 8374214, ~: 8944960)
[PASS] testLength(uint48[],uint256[]) (runs: 1000, μ: 8229725, ~: 8743977)
[PASS] testLookup(uint48[],uint256[],uint48) (runs: 1000, μ: 8020088, ~: 8401941)
[PASS] testPop(uint48[],uint256[]) (runs: 1000, μ: 8003063, ~: 8459821)
[PASS] testPush(uint48[],uint256[],uint48) (runs: 1000, μ: 8466693, ~: 8910861)
[PASS] testUpperLookupRecentCheckpoint(uint48[],uint256[],uint48) (runs: 1000, μ: 8416506, ~: 8763470)
[PASS] testUpperLookupRecentCheckpointWithHint(uint48[],uint256[],uint48,uint32) (runs: 1000, μ: 8288298, ~: 8843347)
[PASS] testUpperLookupRecentWithHint(uint48[],uint256[],uint48,uint32) (runs: 1000, μ: 8203675, ~: 8591646)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 23.05s (26.37s CPU time)
Ran 10 tests for test/libraries/Checkpoints.t.sol:CheckpointsTrace208Test
[PASS] testAt(uint48[],uint208[],uint32) (runs: 1000, μ: 4375909, ~: 4611887)
[PASS] testLatest(uint48[],uint208[]) (runs: 1000, μ: 4207600, ~: 4487922)
[PASS] testLatestCheckpoint(uint48[],uint208[]) (runs: 1000, μ: 4314557, ~: 4530882)
[PASS] testLength(uint48[],uint208[]) (runs: 1000, μ: 4379851, ~: 4590624)
[PASS] testLookup(uint48[],uint208[],uint48) (runs: 1000, μ: 4267805, ~: 4554680)
[PASS] testPop(uint48[],uint208[]) (runs: 1000, μ: 4204937, ~: 4499938)
[PASS] testPush(uint48[],uint208[],uint48) (runs: 1000, μ: 4667616, ~: 4887207)
[PASS] testUpperLookupRecentCheckpoint(uint48[],uint208[],uint48) (runs: 1000, μ: 4430534, ~: 4595657)
[PASS] testUpperLookupRecentCheckpointWithHint(uint48[],uint208[],uint48,uint32) (runs: 1000, μ: 4196282, ~: 4491307)
[PASS] testUpperLookupRecentWithHint(uint48[],uint208[],uint48,uint32) (runs: 1000, μ: 4265766, ~: 4515776)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 23.05s (19.87s CPU time)
Ran 23 tests for test/delegator/FullRestakeDelegator.t.sol:FullRestakeDelegatorTest
[PASS] test_Create(uint48) (runs: 1000, μ: 1126429, ~: 1126343)
[PASS] test_CreateRevertDuplicateRoleHolder1(uint48) (runs: 1000, μ: 1253067, ~: 1252986)
[PASS] test_CreateRevertDuplicateRoleHolder2(uint48) (runs: 1000, μ: 1278343, ~: 1278266)
[PASS] test_CreateRevertMissingRoleHolders(uint48) (runs: 1000, μ: 1226234, ~: 1226149)
[PASS] test_CreateRevertNotVault(uint48) (runs: 1000, μ: 1180225, ~: 1180139)
[PASS] test_CreateRevertZeroAddressRoleHolder1(uint48) (runs: 1000, μ: 1226739, ~: 1226658)
[PASS] test_CreateRevertZeroAddressRoleHolder2(uint48) (runs: 1000, μ: 1252028, ~: 1251938)
[PASS] test_OnSlashRevertNotSlasher(uint48) (runs: 1000, μ: 1067038, ~: 1066948)
[PASS] test_SetHook(uint48) (runs: 1000, μ: 1779295, ~: 1779198)
[PASS] test_SetHookRevertAlreadySet(uint48) (runs: 1000, μ: 1430884, ~: 1430785)
[PASS] test_SetMaxNetworkLimit(uint48,uint256,uint256,uint256) (runs: 1000, μ: 1644003, ~: 1645348)
[PASS] test_SetMaxNetworkLimitRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1269221, ~: 1269174)
[PASS] test_SetMaxNetworkLimitRevertNotNetwork(uint48,uint256) (runs: 1000, μ: 1211582, ~: 1211585)
[PASS] test_SetNetworkLimit(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 1829502, ~: 1830149)
[PASS] test_SetNetworkLimitRevertAlreadySet(uint48,uint256,uint256) (runs: 1000, μ: 1397717, ~: 1397634)
[PASS] test_SetNetworkLimitRevertExceedsMaxNetworkLimit(uint48,uint256,uint256) (runs: 1000, μ: 1265376, ~: 1265362)
[PASS] test_SetOperatorNetworkLimit(uint48,uint256,uint256,uint256,uint256) (runs: 1000, μ: 1868111, ~: 1868612)
[PASS] test_SetOperatorNetworkLimitBoth(uint48,uint256,uint256,uint256) (runs: 1000, μ: 1801756, ~: 1802250)
[PASS] test_SetOperatorNetworkLimitRevertAlreadySet(uint48,uint256) (runs: 1000, μ: 1435407, ~: 1435351)
[PASS] test_Slash(uint48,uint256,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 3610435, ~: 3614872)
[PASS] test_SlashWithHookBase(uint256,uint256,uint256,uint256) (runs: 1000, μ: 3999116, ~: 4007898)
[PASS] test_SlashWithHookGas(uint256,uint256,uint256,uint256) (runs: 1000, μ: 4006717, ~: 3880584)
[PASS] test_Stakes(uint48,uint256,uint256,uint256,uint256,uint256) (runs: 1000, μ: 4673075, ~: 4675451)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 23.05s (11.26s CPU time)
╭-------------------------------------+-----------------+------+--------+------+---------╮
| script/utils/Logs.sol:Logs Contract | | | | | |
+========================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------+-----------------+------+--------+------+---------|
| 734588 | 3701 | | | | |
|-------------------------------------+-----------------+------+--------+------+---------|
| | | | | | |
|-------------------------------------+-----------------+------+--------+------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------+-----------------+------+--------+------+---------|
| log | 4505 | 4586 | 4590 | 4677 | 10 |
╰-------------------------------------+-----------------+------+--------+------+---------╯
╭--------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/DelegatorFactory.sol:DelegatorFactory Contract | | | | | |
+=====================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 476569 | 2499 | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| create | 153385 | 204277 | 205372 | 320820 | 5128 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isEntity | 376 | 376 | 376 | 2376 | 46497 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalTypes | 2472 | 2472 | 2472 | 2472 | 968 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| whitelist | 78934 | 83434 | 79148 | 96276 | 968 |
╰--------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| src/contracts/NetworkRegistry.sol:NetworkRegistry Contract | | | | | |
+=================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 115572 | 603 | | | | |
|------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| isEntity | 2389 | 2389 | 2389 | 2389 | 73403 |
|------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| registerNetwork | 23460 | 89007 | 89221 | 89221 | 23086 |
╰------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭--------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| src/contracts/OperatorRegistry.sol:OperatorRegistry Contract | | | | | |
+===================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 115572 | 603 | | | | |
|--------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|--------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| isEntity | 2389 | 2389 | 2389 | 2389 | 45010 |
|--------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| registerOperator | 23438 | 86088 | 89199 | 89199 | 25675 |
╰--------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭----------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/SlasherFactory.sol:SlasherFactory Contract | | | | | |
+=================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 0 | 2499 | | | | |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| create | 168829 | 215875 | 225360 | 272583 | 1802 |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isEntity | 376 | 377 | 376 | 2376 | 12679 |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalTypes | 2472 | 2472 | 2472 | 2472 | 472 |
|----------------------------------------------------------+-----------------+--------+--------+--------+---------|
| whitelist | 78934 | 87434 | 87434 | 95934 | 472 |
╰----------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭----------------------------------------------------------------+-----------------+---------+--------+---------+---------╮
| src/contracts/VaultConfigurator.sol:VaultConfigurator Contract | | | | | |
+=========================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------------------------+-----------------+---------+--------+---------+---------|
| 342709 | 2019 | | | | |
|----------------------------------------------------------------+-----------------+---------+--------+---------+---------|
| | | | | | |
|----------------------------------------------------------------+-----------------+---------+--------+---------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------------------------+-----------------+---------+--------+---------+---------|
| create | 173717 | 1007600 | 949015 | 1194216 | 46937 |
╰----------------------------------------------------------------+-----------------+---------+--------+---------+---------╯
╭------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/VaultFactory.sol:VaultFactory Contract | | | | | |
+=============================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 0 | 4661 | | | | |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| create | 164807 | 171143 | 169574 | 638657 | 2582 |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isEntity | 448 | 1018 | 448 | 2448 | 82599 |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| lastVersion | 2368 | 2368 | 2368 | 2368 | 49192 |
|------------------------------------------------------+-----------------+--------+--------+--------+---------|
| whitelist | 95353 | 95373 | 95353 | 95441 | 236 |
╰------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭---------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/common/Factory.sol:Factory Contract | | | | | |
+==========================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| 0 | 2499 | | | | |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| blacklist | 25864 | 38148 | 38691 | 49348 | 4 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| blacklisted | 2563 | 2563 | 2563 | 2563 | 3 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| create | 24181 | 103992 | 145804 | 162904 | 5 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| implementation | 2622 | 4060 | 4779 | 4779 | 3 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| isEntity | 2376 | 2376 | 2376 | 2376 | 2 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalTypes | 2472 | 2472 | 2472 | 2472 | 15 |
|---------------------------------------------------+-----------------+--------+--------+--------+---------|
| whitelist | 27057 | 75198 | 87071 | 97698 | 12 |
╰---------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------╮
| src/contracts/common/MigratableEntityProxy.sol:MigratableEntityProxy Contract | | | | | |
+=====================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| 0 | 2083 | | | | |
|-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| | | | | | |
|-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| fallback | 139 | 32212 | 8397 | 355894 | 597325 |
|-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| upgradeToAndCall | 22103 | 22103 | 22103 | 22103 | 1 |
╰-------------------------------------------------------------------------------+-----------------+-------+--------+--------+---------╯
╭-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/common/MigratablesFactory.sol:MigratablesFactory Contract | | | | | |
+================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 909406 | 4661 | | | | |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| blacklist | 23851 | 37744 | 38826 | 49474 | 4 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| blacklisted | 2629 | 2629 | 2629 | 2629 | 3 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| create | 24916 | 409539 | 411750 | 411750 | 523 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| implementation | 569 | 5049 | 5067 | 5067 | 259 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isEntity | 448 | 2355 | 2448 | 2448 | 2753 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| lastVersion | 2368 | 2368 | 2368 | 2368 | 775 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| migrate | 24722 | 81595 | 82092 | 82404 | 516 |
|-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| whitelist | 27214 | 83802 | 78114 | 95353 | 1565 |
╰-------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/delegator/FullRestakeDelegator.sol:FullRestakeDelegator Contract | | | | | |
+=======================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 2224730 | 11645 | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 376 | 376 | 376 | 376 | 241 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| HOOK_GAS_LIMIT | 883 | 883 | 883 | 883 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_LIMIT_SET_ROLE | 575 | 575 | 575 | 575 | 478 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_REGISTRY | 750 | 750 | 750 | 750 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_LIMIT_SET_ROLE | 487 | 487 | 487 | 487 | 4465 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_OPT_IN_SERVICE | 310 | 310 | 310 | 310 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_VAULT_OPT_IN_SERVICE | 288 | 288 | 288 | 288 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 725 | 725 | 725 | 725 | 27598 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 244 | 244 | 244 | 244 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VERSION | 902 | 902 | 902 | 902 | 256 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hasRole | 2995 | 2995 | 2995 | 2995 | 4431 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hook | 2724 | 2724 | 2724 | 2724 | 768 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 29475 | 165927 | 174104 | 194518 | 17694 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| maxNetworkLimit | 2919 | 2919 | 2919 | 2919 | 1233 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimit | 2706 | 5127 | 2706 | 9234 | 22455 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimitAt | 3413 | 10673 | 10397 | 12781 | 4352 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 13703 | 22651 | 15391 | 92742 | 8965 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operatorNetworkLimit | 2672 | 6075 | 9200 | 9200 | 14218 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operatorNetworkLimitAt | 3733 | 11154 | 10717 | 13101 | 4096 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setHook | 9944 | 21619 | 22661 | 31211 | 1024 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setMaxNetworkLimit | 10836 | 36897 | 37072 | 80443 | 12019 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setNetworkLimit | 4652 | 88007 | 99322 | 99322 | 12661 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setOperatorNetworkLimit | 11406 | 89042 | 97709 | 97709 | 20456 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stake | 8809 | 40571 | 48080 | 54608 | 5433 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stakeAt | 1191 | 58041 | 56029 | 73239 | 40456 |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 965 | 996 | 965 | 2965 | 16413 |
╰--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/delegator/NetworkRestakeDelegator.sol:NetworkRestakeDelegator Contract | | | | | |
+=============================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 2321841 | 12130 | | | | |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DEFAULT_ADMIN_ROLE | 662 | 662 | 662 | 662 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 354 | 354 | 354 | 354 | 241 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| HOOK_GAS_LIMIT | 927 | 927 | 927 | 927 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| HOOK_SET_ROLE | 531 | 531 | 531 | 531 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_LIMIT_SET_ROLE | 553 | 553 | 553 | 553 | 777 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_REGISTRY | 750 | 750 | 750 | 750 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_OPT_IN_SERVICE | 288 | 288 | 288 | 288 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_SHARES_SET_ROLE | 861 | 861 | 861 | 861 | 5989 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_VAULT_OPT_IN_SERVICE | 244 | 244 | 244 | 244 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 725 | 725 | 725 | 725 | 35194 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 222 | 222 | 222 | 222 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VERSION | 946 | 946 | 946 | 946 | 256 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hasRole | 2995 | 2995 | 2995 | 2995 | 6766 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hook | 2702 | 2702 | 2702 | 2702 | 1024 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 29475 | 168872 | 174104 | 194518 | 23093 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| maxNetworkLimit | 2941 | 2941 | 2941 | 2941 | 1273 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimit | 2684 | 4439 | 2684 | 9212 | 26672 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimitAt | 3422 | 10640 | 10406 | 12790 | 5120 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 13725 | 56608 | 20019 | 116446 | 1926 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operatorNetworkShares | 2870 | 6001 | 2870 | 9398 | 15108 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operatorNetworkSharesAt | 3337 | 10844 | 10321 | 12705 | 7936 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setHook | 9922 | 21597 | 22639 | 31189 | 1024 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setMaxNetworkLimit | 10814 | 36479 | 37050 | 80421 | 3312 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setNetworkLimit | 4619 | 73358 | 99289 | 99289 | 3181 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setOperatorNetworkShares | 11926 | 122597 | 112330 | 191640 | 9959 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stake | 8853 | 37964 | 21279 | 63824 | 5174 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stakeAt | 4476 | 64509 | 65526 | 88387 | 6024 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalOperatorNetworkShares | 3014 | 9058 | 9542 | 9542 | 3458 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalOperatorNetworkSharesAt | 3510 | 10665 | 10494 | 12878 | 3584 |
|--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 1009 | 1055 | 1009 | 3009 | 22068 |
╰--------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/delegator/OperatorNetworkSpecificDelegator.sol:OperatorNetworkSpecificDelegator Contract | | | | | |
+===============================================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 1961380 | 10401 | | | | |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 310 | 310 | 310 | 310 | 240 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| HOOK_GAS_LIMIT | 795 | 795 | 795 | 795 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_REGISTRY | 662 | 662 | 662 | 662 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_OPT_IN_SERVICE | 244 | 244 | 244 | 244 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_VAULT_OPT_IN_SERVICE | 222 | 222 | 222 | 222 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 637 | 637 | 637 | 637 | 240 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 200 | 200 | 200 | 200 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VERSION | 814 | 814 | 814 | 814 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hook | 2636 | 2636 | 2636 | 2636 | 768 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 80446 | 166619 | 178354 | 178354 | 4352 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| maxNetworkLimit | 2831 | 2831 | 2831 | 2831 | 3072 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| maxNetworkLimitAt | 3259 | 10556 | 10243 | 12627 | 3840 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| network | 2614 | 2614 | 2614 | 2614 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 15303 | 42538 | 26973 | 85338 | 1536 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operator | 2570 | 2570 | 2570 | 2570 | 256 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setHook | 9878 | 21553 | 22595 | 31145 | 1024 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setMaxNetworkLimit | 10770 | 84703 | 79202 | 129798 | 3840 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stake | 8721 | 24558 | 23200 | 43375 | 3328 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stakeAt | 3996 | 43534 | 48195 | 64505 | 2816 |
|--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 877 | 1002 | 877 | 2877 | 4096 |
╰--------------------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/delegator/OperatorSpecificDelegator.sol:OperatorSpecificDelegator Contract | | | | | |
+=================================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 2102325 | 11098 | | | | |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 332 | 332 | 332 | 332 | 240 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| HOOK_GAS_LIMIT | 839 | 839 | 839 | 839 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_LIMIT_SET_ROLE | 531 | 531 | 531 | 531 | 373 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_REGISTRY | 706 | 706 | 706 | 706 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_NETWORK_OPT_IN_SERVICE | 266 | 266 | 266 | 266 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| OPERATOR_VAULT_OPT_IN_SERVICE | 244 | 244 | 244 | 244 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 681 | 681 | 681 | 681 | 12869 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 222 | 222 | 222 | 222 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VERSION | 858 | 858 | 858 | 858 | 256 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hasRole | 2973 | 2973 | 2973 | 2973 | 117 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hook | 2680 | 2680 | 2680 | 2680 | 768 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 29401 | 151861 | 176359 | 196772 | 6412 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| maxNetworkLimit | 2875 | 2875 | 2875 | 2875 | 1016 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimit | 2662 | 7710 | 9190 | 9190 | 4029 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| networkLimitAt | 3369 | 10587 | 10353 | 12737 | 5120 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 13659 | 46249 | 19953 | 85423 | 1915 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| operator | 2592 | 2592 | 2592 | 2592 | 12397 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setHook | 9900 | 21575 | 22617 | 31167 | 1024 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setMaxNetworkLimit | 10792 | 36411 | 37028 | 80399 | 3203 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setNetworkLimit | 4619 | 69447 | 68576 | 99289 | 3764 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stake | 8765 | 24253 | 21049 | 47742 | 3328 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| stakeAt | 20587 | 45255 | 46043 | 62349 | 2939 |
|------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 921 | 1020 | 921 | 2921 | 5132 |
╰------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭--------------------------------------------------------------------+-----------------+-------+--------+--------+---------╮
| src/contracts/service/MetadataService.sol:MetadataService Contract | | | | | |
+==========================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| 257737 | 1451 | | | | |
|--------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| metadataURL | 2927 | 4012 | 2931 | 9564 | 512 |
|--------------------------------------------------------------------+-----------------+-------+--------+--------+---------|
| setMetadataURL | 27177 | 53252 | 45195 | 120809 | 1024 |
╰--------------------------------------------------------------------+-----------------+-------+--------+--------+---------╯
╭--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| src/contracts/service/NetworkMiddlewareService.sol:NetworkMiddlewareService Contract | | | | | |
+===========================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 120202 | 764 | | | | |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| NETWORK_REGISTRY | 223 | 223 | 223 | 223 | 256 |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| middleware | 115 | 2409 | 2411 | 2411 | 23550 |
|--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setMiddleware | 26722 | 50205 | 50702 | 50702 | 23554 |
╰--------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭--------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/service/OptInService.sol:OptInService Contract | | | | | |
+=====================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 1212661 | 7461 | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| WHERE_REGISTRY | 222 | 222 | 222 | 222 | 1 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| eip712Domain | 1269 | 1269 | 1269 | 1269 | 7 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| increaseNonce | 45534 | 45534 | 45534 | 45534 | 1 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isOptedIn | 2663 | 4011 | 4866 | 4866 | 85439 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isOptedInAt | 3312 | 5946 | 5939 | 8238 | 98592 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| nonces | 2699 | 2699 | 2699 | 2699 | 4 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| optIn(address) | 27256 | 103486 | 103511 | 103523 | 34243 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| optIn(address,address,uint48,bytes) | 24233 | 50759 | 34102 | 110600 | 4 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| optOut(address) | 24330 | 43619 | 44239 | 61670 | 4 |
|--------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| optOut(address,address,uint48,bytes) | 24157 | 42271 | 34002 | 68655 | 3 |
╰--------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭----------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/slasher/Slasher.sol:Slasher Contract | | | | | |
+===========================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| 1525061 | 8015 | | | | |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| BURNER_GAS_LIMIT | 443 | 443 | 443 | 443 | 256 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 310 | 310 | 310 | 310 | 241 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_MIDDLEWARE_SERVICE | 288 | 288 | 288 | 288 | 256 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 439 | 439 | 439 | 439 | 240 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 200 | 200 | 200 | 200 | 256 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| cumulativeSlash | 2628 | 8503 | 9156 | 9156 | 2560 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| cumulativeSlashAt | 3493 | 9095 | 10477 | 12782 | 6400 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 29326 | 72114 | 72768 | 86356 | 6825 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| latestSlashedCaptureTimestamp | 2561 | 2561 | 2561 | 2561 | 1280 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| slash | 23 | 260076 | 279879 | 419643 | 12816 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| slashableStake | 14151 | 62172 | 85954 | 102639 | 9472 |
|----------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 588 | 708 | 588 | 2588 | 6435 |
╰----------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/slasher/VetoSlasher.sol:VetoSlasher Contract | | | | | |
+===================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 2374544 | 12320 | | | | |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 288 | 288 | 288 | 288 | 241 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_MIDDLEWARE_SERVICE | 266 | 266 | 266 | 266 | 256 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| NETWORK_REGISTRY | 596 | 596 | 596 | 596 | 256 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| TYPE | 549 | 549 | 549 | 549 | 240 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| VAULT_FACTORY | 178 | 178 | 178 | 178 | 256 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| cumulativeSlash | 9149 | 9149 | 9149 | 9149 | 1536 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| cumulativeSlashAt | 5876 | 8780 | 10527 | 12826 | 3072 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| executeSlash | 8169 | 211164 | 293043 | 356654 | 3840 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 29337 | 113367 | 118916 | 132416 | 7710 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| latestSlashedCaptureTimestamp | 2539 | 2539 | 2539 | 2539 | 1536 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| requestSlash | 11271 | 185712 | 213385 | 213393 | 6912 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| resolver | 3500 | 7065 | 8426 | 8426 | 1792 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| resolverAt | 3139 | 6430 | 5766 | 8144 | 2560 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| resolverSetEpochsDelay | 2656 | 2656 | 2656 | 2656 | 256 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setResolver | 11407 | 53892 | 60557 | 62600 | 5376 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| slashRequests | 2535 | 10800 | 11351 | 11351 | 4096 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| slashRequestsLength | 2480 | 2480 | 2480 | 2480 | 256 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vault | 808 | 881 | 808 | 2808 | 6941 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vetoDuration | 2750 | 2750 | 2750 | 2750 | 768 |
|------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| vetoSlash | 8302 | 18651 | 19141 | 26487 | 2048 |
╰------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭----------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/vault/Vault.sol:Vault Contract | | | | | |
+=====================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| 3823732 | 19435 | | | | |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| DEFAULT_ADMIN_ROLE | 1124 | 1124 | 1124 | 1124 | 512 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| DELEGATOR_FACTORY | 750 | 750 | 750 | 750 | 256 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSITOR_WHITELIST_ROLE | 201 | 201 | 201 | 201 | 771 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSIT_LIMIT_SET_ROLE | 1147 | 1147 | 1147 | 1147 | 1280 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSIT_WHITELIST_SET_ROLE | 1477 | 1477 | 1477 | 1477 | 518 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 376 | 376 | 376 | 376 | 185 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| IS_DEPOSIT_LIMIT_SET_ROLE | 179 | 179 | 179 | 179 | 1282 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| SLASHER_FACTORY | 992 | 992 | 992 | 992 | 256 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeBalanceOf | 7681 | 25158 | 27057 | 27057 | 2984 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeBalanceOfAt | 9583 | 33990 | 32665 | 53283 | 7424 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeShares | 3560 | 9341 | 9984 | 9984 | 2560 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesAt | 3465 | 11539 | 10597 | 17418 | 6912 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesOf | 3404 | 9338 | 9932 | 9932 | 2816 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesOfAt | 3373 | 11144 | 10599 | 17573 | 6400 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeStake | 3516 | 9248 | 9940 | 9940 | 11893 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| activeStakeAt | 2873 | 11815 | 11213 | 17770 | 59143 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| burner | 394 | 655 | 394 | 2394 | 15691 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| claim | 6483 | 32684 | 14611 | 75745 | 1536 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| claimBatch | 6303 | 40907 | 38995 | 106820 | 1536 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| collateral | 3590 | 3590 | 3590 | 3590 | 6549 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| currentEpoch | 3213 | 3213 | 3213 | 3213 | 17920 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| currentEpochStart | 3389 | 3389 | 3389 | 3389 | 3328 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| delegator | 1331 | 3348 | 3538 | 3538 | 134934 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| deposit | 5707 | 314949 | 329711 | 336946 | 20256 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| depositLimit | 3602 | 3602 | 3602 | 3602 | 1280 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| depositWhitelist | 2623 | 2623 | 2623 | 2623 | 1053 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| epochAt | 3128 | 3274 | 3293 | 3293 | 2304 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| epochDuration | 516 | 1947 | 2640 | 2640 | 82242 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| epochDurationInit | 2580 | 2580 | 2580 | 2580 | 256 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| grantRole | 7329 | 7329 | 7329 | 7329 | 2059 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| hasRole | 3413 | 3413 | 3413 | 3413 | 1792 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 72087 | 237693 | 244147 | 264047 | 40281 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isDelegatorInitialized | 2674 | 2674 | 2674 | 2674 | 258 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isDepositLimit | 3223 | 3223 | 3223 | 3223 | 541 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isDepositorWhitelisted | 3123 | 3123 | 3123 | 3123 | 257 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isInitialized | 2562 | 4686 | 4691 | 4691 | 514 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isSlasherInitialized | 2872 | 2872 | 2872 | 2872 | 258 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| isWithdrawalsClaimed | 3557 | 3557 | 3557 | 3557 | 768 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| nextEpochStart | 3530 | 3530 | 3530 | 3530 | 1024 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 8133 | 77865 | 100902 | 111547 | 12027 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| owner | 3174 | 3174 | 3174 | 3174 | 13240 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| previousEpochStart | 2692 | 2877 | 2877 | 3062 | 1024 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| redeem | 5437 | 116704 | 31803 | 266133 | 1280 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setDelegator | 8248 | 27474 | 27473 | 43773 | 38738 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositLimit | 10771 | 24010 | 31917 | 31917 | 1792 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositWhitelist | 9975 | 13589 | 14041 | 14041 | 9 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositorWhitelistStatus | 8677 | 21235 | 21786 | 32691 | 4 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setIsDepositLimit | 10146 | 14229 | 14233 | 14233 | 1284 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| setSlasher | 8534 | 26006 | 25175 | 43938 | 38739 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| slashableBalanceOf | 24608 | 42223 | 43984 | 43984 | 2817 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| slasher | 3428 | 3428 | 3428 | 3428 | 14343 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| totalStake | 9978 | 16122 | 16402 | 16402 | 5890 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| withdraw | 6776 | 217032 | 267530 | 267530 | 6972 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawalShares | 3447 | 3447 | 3447 | 3447 | 3840 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawalSharesOf | 3523 | 3523 | 3523 | 3523 | 3584 |
|----------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawals | 2853 | 2853 | 2853 | 2853 | 5376 |
╰----------------------------------------------+-----------------+--------+--------+--------+---------╯
╭----------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| src/contracts/vault/VaultTokenized.sol:VaultTokenized Contract | | | | | |
+=======================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 4440153 | 22513 | | | | |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DEFAULT_ADMIN_ROLE | 1278 | 1278 | 1278 | 1278 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DELEGATOR_FACTORY | 860 | 860 | 860 | 860 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSITOR_WHITELIST_ROLE | 267 | 267 | 267 | 267 | 515 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSIT_LIMIT_SET_ROLE | 1301 | 1301 | 1301 | 1301 | 1024 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| DEPOSIT_WHITELIST_SET_ROLE | 1653 | 1653 | 1653 | 1653 | 262 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| FACTORY | 464 | 464 | 464 | 464 | 60 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| IS_DEPOSIT_LIMIT_SET_ROLE | 223 | 223 | 223 | 223 | 1026 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| SLASHER_FACTORY | 1124 | 1124 | 1124 | 1124 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeBalanceOf | 7791 | 25405 | 27167 | 27167 | 2816 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeBalanceOfAt | 9781 | 34188 | 32863 | 53481 | 7424 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeShares | 3736 | 9623 | 10160 | 10160 | 3066 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesAt | 3575 | 11649 | 10707 | 17528 | 6912 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesOf | 3558 | 9601 | 10086 | 10086 | 3447 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeSharesOfAt | 3461 | 11232 | 10687 | 17661 | 6400 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeStake | 3692 | 9621 | 10116 | 10116 | 3328 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| activeStakeAt | 3949 | 12092 | 13176 | 17902 | 8448 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| allowance | 4126 | 4126 | 4126 | 4126 | 381 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| approve | 24436 | 24436 | 24436 | 24436 | 125 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| balanceOf | 3228 | 9066 | 9756 | 9756 | 2423 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| burner | 482 | 2149 | 2482 | 2482 | 1540 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| claim | 6659 | 32860 | 14787 | 75921 | 1536 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| claimBatch | 6435 | 41039 | 39127 | 106952 | 1536 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| collateral | 3766 | 3766 | 3766 | 3766 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| currentEpoch | 3345 | 3345 | 3345 | 3345 | 17920 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| currentEpochStart | 3499 | 3499 | 3499 | 3499 | 1024 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| decimals | 5791 | 5791 | 5791 | 5791 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| delegator | 1714 | 2914 | 3714 | 3714 | 1281 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| deposit | 5817 | 302625 | 331615 | 338850 | 7941 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| depositLimit | 3800 | 3800 | 3800 | 3800 | 1024 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| depositWhitelist | 2733 | 2733 | 2733 | 2733 | 514 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| epochAt | 3260 | 3406 | 3425 | 3425 | 2304 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| epochDuration | 750 | 2500 | 2750 | 2750 | 4096 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| epochDurationInit | 2690 | 2690 | 2690 | 2690 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| grantRole | 7417 | 7417 | 7417 | 7417 | 2059 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| hasRole | 3545 | 3545 | 3545 | 3545 | 512 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| initialize | 75458 | 256724 | 292979 | 292979 | 9238 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isDelegatorInitialized | 2784 | 2784 | 2784 | 2784 | 258 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isDepositLimit | 3377 | 3377 | 3377 | 3377 | 2 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isDepositorWhitelisted | 3255 | 3255 | 3255 | 3255 | 257 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isInitialized | 2672 | 4792 | 4801 | 4801 | 258 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isSlasherInitialized | 2982 | 2982 | 2982 | 2982 | 258 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| isWithdrawalsClaimed | 3711 | 3711 | 3711 | 3711 | 768 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| name | 2915 | 2915 | 2915 | 2915 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| nextEpochStart | 3662 | 3662 | 3662 | 3662 | 1024 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| onSlash | 8265 | 78378 | 48149 | 111679 | 513 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| owner | 3306 | 3306 | 3306 | 3306 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| previousEpochStart | 2780 | 2965 | 2965 | 3150 | 1024 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| redeem | 5503 | 117554 | 31869 | 268042 | 1280 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setDelegator | 8380 | 27646 | 27649 | 43905 | 7695 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositLimit | 10947 | 24186 | 32093 | 32093 | 1792 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositWhitelist | 10085 | 13699 | 14151 | 14151 | 9 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setDepositorWhitelistStatus | 8831 | 21389 | 21940 | 32845 | 4 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setIsDepositLimit | 10256 | 14339 | 14343 | 14343 | 1284 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| setSlasher | 8710 | 25434 | 25351 | 44114 | 7696 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| slashableBalanceOf | 24784 | 42398 | 44160 | 44160 | 2816 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| slasher | 3604 | 3604 | 3604 | 3604 | 769 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| symbol | 3927 | 3927 | 3927 | 3927 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalStake | 10110 | 16156 | 16534 | 16534 | 4352 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| totalSupply | 2438 | 8146 | 8862 | 8862 | 2298 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| transfer | 10503 | 59425 | 10503 | 110696 | 256 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| transferFrom | 35972 | 36108 | 35972 | 53072 | 125 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| withdraw | 6974 | 231728 | 269571 | 269571 | 6144 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawalShares | 3623 | 3623 | 3623 | 3623 | 3840 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawalSharesOf | 3677 | 3677 | 3677 | 3677 | 3584 |
|----------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| withdrawals | 2963 | 2963 | 2963 | 2963 | 5376 |
╰----------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| test/integration/actions/ActionScripts.t.sol:OptInNetworkScriptHarness Contract | | | | | |
+========================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 647731 | 2821 | | | | |
|---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| runBase | 128622 | 128622 | 128622 | 128622 | 1 |
╰---------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| test/integration/actions/ActionScripts.t.sol:OptInVaultScriptHarness Contract | | | | | |
+======================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 646843 | 2817 | | | | |
|-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| runBase | 128681 | 128681 | 128681 | 128681 | 1 |
╰-------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/integration/actions/ActionScripts.t.sol:RegisterOperatorScriptHarness Contract | | | | | |
+==========================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 587364 | 2541 | | | | |
|-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| runBase | 96162 | 96162 | 96162 | 96162 | 1 |
╰-------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/integration/actions/ActionScripts.t.sol:SetHookScriptHarness Contract | | | | | |
+=================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 465893 | 1980 | | | | |
|----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| runBase | 89401 | 89401 | 89401 | 89401 | 1 |
╰----------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/integration/actions/ActionScripts.t.sol:SetMaxNetworkLimitScriptHarness Contract | | | | | |
+============================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 502417 | 2149 | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| runBase | 96428 | 96428 | 96428 | 96428 | 1 |
╰---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| test/integration/actions/ActionScripts.t.sol:SetNetworkLimitScriptHarness Contract | | | | | |
+===========================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 496816 | 2123 | | | | |
|------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| runBase | 161767 | 161767 | 161767 | 161767 | 1 |
╰------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| test/integration/actions/ActionScripts.t.sol:SetOperatorNetworkSharesScriptHarness Contract | | | | | |
+====================================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 533902 | 2295 | | | | |
|---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| runBase | 255470 | 255470 | 255470 | 255470 | 1 |
╰---------------------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮
| test/integration/actions/ActionScripts.t.sol:SetResolverScriptHarness Contract | | | | | |
+=======================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| 505885 | 2165 | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| | | | | | |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------|
| runBase | 120467 | 120467 | 120467 | 120467 | 2 |
╰--------------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯
╭------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/integration/actions/ActionScripts.t.sol:VetoSlashScriptHarness Contract | | | | | |
+===================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 476500 | 2029 | | | | |
|------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| runBase | 82322 | 82322 | 82322 | 82322 | 1 |
╰------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/libraries/Checkpoints.t.sol:CheckpointsTrace208Test Contract | | | | | |
+========================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 2625037 | 12939 | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| push | 26593 | 26707 | 26641 | 26917 | 256 |
╰-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/libraries/Checkpoints.t.sol:CheckpointsTrace256Test Contract | | | | | |
+========================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 2711744 | 13372 | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| push | 31747 | 31886 | 31807 | 32143 | 256 |
╰-------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭-----------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/FakeEntity.sol:FakeEntity Contract | | | | | |
+====================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| 136309 | 587 | | | | |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| FACTORY | 196 | 196 | 196 | 196 | 2 |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| TYPE | 2305 | 2305 | 2305 | 2305 | 2 |
|-----------------------------------------------+-----------------+-------+--------+-------+---------|
| setType | 43595 | 43595 | 43595 | 43595 | 1 |
╰-----------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/FeeOnTransferToken.sol:FeeOnTransferToken Contract | | | | | |
+====================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 517987 | 2791 | | | | |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| approve | 45899 | 45967 | 45995 | 46019 | 1229 |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| balanceOf | 530 | 1854 | 2530 | 2530 | 3637 |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| decimals | 253 | 253 | 253 | 253 | 6767 |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| totalSupply | 2315 | 2315 | 2315 | 2315 | 71 |
|---------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| transfer | 58419 | 58471 | 58467 | 58515 | 1024 |
╰---------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------+-----------------+------+--------+------+---------╮
| test/mocks/SimpleBurner.sol:SimpleBurner Contract | | | | | |
+======================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------+-----------------+------+--------+------+---------|
| 265563 | 1140 | | | | |
|---------------------------------------------------+-----------------+------+--------+------+---------|
| | | | | | |
|---------------------------------------------------+-----------------+------+--------+------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------+-----------------+------+--------+------+---------|
| counter1 | 2253 | 2253 | 2253 | 2253 | 646 |
╰---------------------------------------------------+-----------------+------+--------+------+---------╯
╭---------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleEntity.sol:SimpleEntity Contract | | | | | |
+========================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| 218931 | 1008 | | | | |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| FACTORY | 196 | 196 | 196 | 196 | 13 |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| TYPE | 228 | 228 | 228 | 228 | 11 |
|---------------------------------------------------+-----------------+-------+--------+-------+---------|
| initialize | 2707 | 18666 | 23986 | 23986 | 4 |
╰---------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleFullRestakeDelegatorHook.sol:SimpleFullRestakeDelegatorHook Contract | | | | | |
+============================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 290793 | 1124 | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setData | 33433 | 52024 | 52029 | 70625 | 1024 |
╰---------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleMigratableEntity.sol:SimpleMigratableEntity Contract | | | | | |
+============================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 427926 | 1928 | | | | |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| FACTORY | 227 | 227 | 227 | 227 | 1042 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| a | 2260 | 2260 | 2260 | 2260 | 256 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| initialize | 2735 | 70771 | 70902 | 70902 | 521 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| migrate | 2598 | 2598 | 2598 | 2598 | 1 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| owner | 2456 | 2456 | 2456 | 2456 | 515 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setA | 2506 | 22172 | 22406 | 22406 | 256 |
|-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| version | 2375 | 2375 | 2375 | 2375 | 515 |
╰-----------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleMigratableEntityV2.sol:SimpleMigratableEntityV2 Contract | | | | | |
+================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 477124 | 2156 | | | | |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| FACTORY | 249 | 249 | 249 | 249 | 517 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| a | 2282 | 2282 | 2282 | 2282 | 512 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| b | 2359 | 2359 | 2359 | 2359 | 512 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| migrate | 9236 | 28941 | 29136 | 29136 | 512 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setA | 5389 | 5589 | 5389 | 22489 | 256 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setB | 2349 | 5271 | 5149 | 22249 | 256 |
|---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| version | 2419 | 2419 | 2419 | 2419 | 256 |
╰---------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleNetworkRestakeDelegatorHook.sol:SimpleNetworkRestakeDelegatorHook Contract | | | | | |
+==================================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 290793 | 1124 | | | | |
|---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------|
| setData | 33433 | 52039 | 52029 | 70625 | 1024 |
╰---------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------╮
| test/mocks/SimpleOperatorNetworkSpecificDelegatorHook.sol:SimpleOperatorNetworkSpecificDelegatorHook Contract | | | | | |
+==================================================================================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------|
| 138383 | 420 | | | | |
|---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------|
| | | | | | |
|---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------|
| counter1 | 2247 | 2247 | 2247 | 2247 | 1024 |
╰---------------------------------------------------------------------------------------------------------------+-----------------+------+--------+------+---------╯
╭-------------------------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/SimpleRegistry.sol:SimpleRegistry Contract | | | | | |
+============================================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| 168403 | 559 | | | | |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| entity | 2352 | 3418 | 3418 | 4485 | 6 |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| isEntity | 2368 | 2368 | 2368 | 2368 | 4 |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| register | 71933 | 80483 | 80483 | 89033 | 2 |
|-------------------------------------------------------+-----------------+-------+--------+-------+---------|
| totalEntities | 2299 | 2299 | 2299 | 2299 | 3 |
╰-------------------------------------------------------+-----------------+-------+--------+-------+---------╯
╭-------------------------------------+-----------------+-------+--------+-------+---------╮
| test/mocks/Token.sol:Token Contract | | | | | |
+==========================================================================================+
| Deployment Cost | Deployment Size | | | | |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| 493828 | 2680 | | | | |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| | | | | | |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| Function Name | Min | Avg | Median | Max | # Calls |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| approve | 45899 | 45964 | 45971 | 46019 | 26453 |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| balanceOf | 530 | 1651 | 2530 | 2530 | 60238 |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| decimals | 253 | 253 | 253 | 253 | 5227 |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| totalSupply | 2315 | 2315 | 2315 | 2315 | 76 |
|-------------------------------------+-----------------+-------+--------+-------+---------|
| transfer | 51184 | 51237 | 51244 | 51280 | 26374 |
╰-------------------------------------+-----------------+-------+--------+-------+---------╯
Ran 28 test suites in 36.99s (174.99s CPU time): 317 tests passed, 0 failed, 0 skipped (317 total tests)
````
## File: snapshots/sizes.txt
````
No files changed, compilation skipped
╭----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------╮
| Contract | Runtime Size (B) | Initcode Size (B) | Runtime Margin (B) | Initcode Margin (B) |
+====================================================================================================================================================================+
| Address | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| BaseDelegatorHints | 2,696 | 17,478 | 21,880 | 31,674 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| BaseSlasherHints | 3,080 | 8,726 | 21,496 | 40,426 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Checkpoints (lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol) | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Checkpoints (src/contracts/libraries/Checkpoints.sol) | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Clones | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Create2 | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| CreateXWrapper | 2,335 | 2,361 | 22,241 | 46,791 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| DAILikeToken | 2,887 | 4,014 | 21,689 | 45,138 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| DelegatorFactory | 2,261 | 2,467 | 22,315 | 46,685 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| ECDSA | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| ERC1967Proxy | 130 | 689 | 24,446 | 48,463 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| ERC1967Utils | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| ERC4626Math | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| EnumerableSet | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Factory | 2,261 | 2,467 | 22,315 | 46,685 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| FakeEntity | 362 | 523 | 24,214 | 48,629 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| FeeOnTransferToken | 1,748 | 2,695 | 22,828 | 46,457 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| FullRestakeDelegator | 10,991 | 11,453 | 13,585 | 37,699 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| FullRestakeDelegatorHints | 3,394 | 3,595 | 21,182 | 45,557 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Logs | 3,669 | 3,701 | 20,907 | 45,451 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Math | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| MessageHashUtils | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| MetadataService | 1,286 | 1,419 | 23,290 | 47,733 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| MigratableEntityProxy | 808 | 1,475 | 23,768 | 47,677 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| MigratablesFactory | 4,423 | 4,629 | 20,153 | 44,523 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| NetworkMiddlewareService | 599 | 732 | 23,977 | 48,420 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| NetworkRegistry | 577 | 603 | 23,999 | 48,549 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| NetworkRestakeDelegator | 11,476 | 11,938 | 13,100 | 37,214 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| NetworkRestakeDelegatorHints | 3,681 | 3,889 | 20,895 | 45,263 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OperatorNetworkSpecificDelegator | 9,675 | 10,177 | 14,901 | 38,975 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OperatorNetworkSpecificDelegatorHints | 3,232 | 3,426 | 21,344 | 45,726 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OperatorRegistry | 577 | 603 | 23,999 | 48,549 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OperatorSpecificDelegator | 10,379 | 10,874 | 14,197 | 38,278 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OperatorSpecificDelegatorHints | 3,122 | 3,315 | 21,454 | 45,837 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OptInService | 6,048 | 7,301 | 18,528 | 41,851 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| OptInServiceHints | 1,981 | 2,019 | 22,595 | 47,133 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| PermitToken | 3,513 | 5,435 | 21,063 | 43,717 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| RebaseToken | 2,121 | 3,074 | 22,455 | 46,078 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SafeCast | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SafeERC20 | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| ShortStrings | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SignatureChecker | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SignedMath | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleBurner | 975 | 1,108 | 23,601 | 48,044 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleEntity | 639 | 944 | 23,937 | 48,208 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleFullRestakeDelegatorHook | 1,098 | 1,124 | 23,478 | 48,028 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleMigratableEntity | 1,609 | 1,896 | 22,967 | 47,256 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleMigratableEntityV2 | 1,837 | 2,124 | 22,739 | 47,028 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleNetworkRestakeDelegatorHook | 1,098 | 1,124 | 23,478 | 48,028 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleOperatorNetworkSpecificDelegatorHook | 394 | 420 | 24,182 | 48,732 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleOperatorSpecificDelegatorHook | 512 | 538 | 24,064 | 48,614 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SimpleRegistry | 533 | 559 | 24,043 | 48,593 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Simulation | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Slasher | 7,498 | 7,887 | 17,078 | 41,265 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SlasherFactory | 2,261 | 2,467 | 22,315 | 46,685 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SlasherHints | 924 | 1,067 | 23,652 | 48,085 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| StorageSlot | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Strings | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Subnetwork | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SymbioticCoreBytecode | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SymbioticCoreConstants | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| SymbioticUtils | 116 | 143 | 24,460 | 49,009 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Time | 57 | 85 | 24,519 | 49,067 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Token | 1,637 | 2,584 | 22,939 | 46,568 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| Vault | 18,978 | 19,339 | 5,598 | 29,813 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VaultConfigurator | 1,709 | 1,923 | 22,867 | 47,229 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VaultFactory | 4,423 | 4,629 | 20,153 | 44,523 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VaultHints | 4,514 | 4,567 | 20,062 | 44,585 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VaultTokenized | 22,056 | 22,417 | 2,520 | 26,735 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VetoSlasher | 11,740 | 12,160 | 12,836 | 36,992 |
|----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------|
| VetoSlasherHints | 4,131 | 4,285 | 20,445 | 44,867 |
╰----------------------------------------------------------------------------------+------------------+-------------------+--------------------+---------------------╯
````
## File: src/contracts/common/Entity.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IEntity} from "../../interfaces/common/IEntity.sol";
⋮----
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
⋮----
abstract contract Entity is Initializable, IEntity {
/**
* @inheritdoc IEntity
*/
⋮----
function initialize(bytes calldata data) external initializer {
⋮----
function _initialize(
bytes calldata /* data */
````
## File: src/contracts/common/Factory.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Registry} from "./Registry.sol";
⋮----
import {IEntity} from "../../interfaces/common/IEntity.sol";
import {IFactory} from "../../interfaces/common/IFactory.sol";
⋮----
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
⋮----
contract Factory is Registry, Ownable, IFactory {
⋮----
/**
* @inheritdoc IFactory
*/
⋮----
modifier checkType(uint64 type_) {
⋮----
function totalTypes() public view returns (uint64) {
⋮----
function implementation(uint64 type_) public view returns (address) {
⋮----
function whitelist(address implementation_) external onlyOwner {
⋮----
function blacklist(uint64 type_) external onlyOwner checkType(type_) {
⋮----
function create(uint64 type_, bytes calldata data) external returns (address entity_) {
````
## File: src/contracts/common/MigratableEntity.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IMigratableEntity} from "../../interfaces/common/IMigratableEntity.sol";
⋮----
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
⋮----
abstract contract MigratableEntity is Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable, IMigratableEntity {
/**
* @inheritdoc IMigratableEntity
*/
⋮----
modifier notInitialized() {
⋮----
function version() external view returns (uint64) {
⋮----
function initialize(uint64 initialVersion, address owner_, bytes calldata data)
⋮----
function migrate(uint64 newVersion, bytes calldata data) external nonReentrant {
⋮----
function _migrateInternal(uint64 oldVersion, uint64 newVersion, bytes calldata data)
⋮----
function _initialize(
⋮----
/* initialVersion */
⋮----
/* owner */
bytes memory /* data */
⋮----
function _migrate(
⋮----
/* oldVersion */
⋮----
/* newVersion */
bytes calldata /* data */
````
## File: src/contracts/common/MigratableEntityProxy.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IMigratableEntityProxy} from "../../interfaces/common/IMigratableEntityProxy.sol";
⋮----
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
⋮----
contract MigratableEntityProxy is ERC1967Proxy, IMigratableEntityProxy {
// An immutable address for the admin to avoid unnecessary SLOADs before each call.
⋮----
/**
* @dev The proxy caller is the current admin, and can't fallback to the proxy target.
*/
⋮----
/**
* @dev Initializes an upgradeable proxy managed by `msg.sender`,
* backed by the implementation at `logic`, and optionally initialized with `data` as explained in
* {ERC1967Proxy-constructor}.
*/
⋮----
// Set the storage value and emit an event for ERC-1967 compatibility
⋮----
/**
* @inheritdoc IMigratableEntityProxy
*/
function upgradeToAndCall(address newImplementation, bytes calldata data) external {
⋮----
/**
* @dev Returns the admin of this proxy.
*/
function _proxyAdmin() internal view returns (address) {
````
## File: src/contracts/common/MigratablesFactory.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {MigratableEntityProxy} from "./MigratableEntityProxy.sol";
import {Registry} from "./Registry.sol";
⋮----
import {IMigratableEntityProxy} from "../../interfaces/common/IMigratableEntityProxy.sol";
import {IMigratableEntity} from "../../interfaces/common/IMigratableEntity.sol";
import {IMigratablesFactory} from "../../interfaces/common/IMigratablesFactory.sol";
⋮----
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
⋮----
contract MigratablesFactory is Registry, Ownable, IMigratablesFactory {
⋮----
/**
* @inheritdoc IMigratablesFactory
*/
⋮----
modifier checkVersion(uint64 version) {
⋮----
function lastVersion() public view returns (uint64) {
⋮----
function implementation(uint64 version) public view checkVersion(version) returns (address) {
⋮----
function whitelist(address implementation_) external onlyOwner {
⋮----
function blacklist(uint64 version) external onlyOwner checkVersion(version) {
⋮----
function create(uint64 version, address owner_, bytes calldata data) external returns (address entity_) {
⋮----
function migrate(address entity_, uint64 newVersion, bytes calldata data) external checkEntity(entity_) {
````
## File: src/contracts/common/Registry.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
⋮----
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
⋮----
abstract contract Registry is IRegistry {
⋮----
modifier checkEntity(address account) {
⋮----
/**
* @inheritdoc IRegistry
*/
function isEntity(address entity_) public view returns (bool) {
⋮----
function totalEntities() public view returns (uint256) {
⋮----
function entity(uint256 index) public view returns (address) {
⋮----
function _addEntity(address entity_) internal {
⋮----
function _checkEntity(address account) internal view {
````
## File: src/contracts/common/StaticDelegateCallable.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IStaticDelegateCallable} from "../../interfaces/common/IStaticDelegateCallable.sol";
⋮----
abstract contract StaticDelegateCallable is IStaticDelegateCallable {
/**
* @inheritdoc IStaticDelegateCallable
*/
function staticDelegateCall(address target, bytes calldata data) external {
````
## File: src/contracts/delegator/BaseDelegator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Entity} from "../common/Entity.sol";
import {StaticDelegateCallable} from "../common/StaticDelegateCallable.sol";
⋮----
import {Subnetwork} from "../libraries/Subnetwork.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IDelegatorHook} from "../../interfaces/delegator/IDelegatorHook.sol";
import {IOptInService} from "../../interfaces/service/IOptInService.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
⋮----
abstract contract BaseDelegator is
⋮----
/**
* @inheritdoc IBaseDelegator
*/
⋮----
function VERSION() external pure returns (uint64) {
⋮----
function stakeAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hints)
⋮----
function stake(bytes32 subnetwork, address operator) external view returns (uint256) {
⋮----
function setMaxNetworkLimit(uint96 identifier, uint256 amount) external nonReentrant {
⋮----
function setHook(address hook_) external nonReentrant onlyRole(HOOK_SET_ROLE) {
⋮----
function onSlash(bytes32 subnetwork, address operator, uint256 amount, uint48 captureTimestamp, bytes memory data)
⋮----
function _initialize(bytes calldata data) internal override {
⋮----
function _stakeAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hints)
⋮----
function _stake(bytes32 subnetwork, address operator) internal view virtual returns (uint256) {}
⋮----
function _setMaxNetworkLimit(bytes32 subnetwork, uint256 amount) internal virtual {}
⋮----
function __initialize(address vault_, bytes memory data) internal virtual returns (BaseParams memory) {}
````
## File: src/contracts/delegator/FullRestakeDelegator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseDelegator} from "./BaseDelegator.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IFullRestakeDelegator} from "../../interfaces/delegator/IFullRestakeDelegator.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
⋮----
/**
* @inheritdoc IFullRestakeDelegator
*/
⋮----
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function networkLimit(bytes32 subnetwork) public view returns (uint256) {
⋮----
function operatorNetworkLimitAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
function operatorNetworkLimit(bytes32 subnetwork, address operator) public view returns (uint256) {
⋮----
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external onlyRole(NETWORK_LIMIT_SET_ROLE) {
⋮----
function setOperatorNetworkLimit(bytes32 subnetwork, address operator, uint256 amount)
⋮----
function _stakeAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hints)
⋮----
function _stake(bytes32 subnetwork, address operator) internal view override returns (uint256) {
⋮----
function _setMaxNetworkLimit(bytes32 subnetwork, uint256 amount) internal override {
⋮----
function __initialize(address, bytes memory data) internal override returns (IBaseDelegator.BaseParams memory) {
````
## File: src/contracts/delegator/NetworkRestakeDelegator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseDelegator} from "./BaseDelegator.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "../../interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
⋮----
/**
* @inheritdoc INetworkRestakeDelegator
*/
⋮----
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function networkLimit(bytes32 subnetwork) public view returns (uint256) {
⋮----
function totalOperatorNetworkSharesAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint)
⋮----
function totalOperatorNetworkShares(bytes32 subnetwork) public view returns (uint256) {
⋮----
function operatorNetworkSharesAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
function operatorNetworkShares(bytes32 subnetwork, address operator) public view returns (uint256) {
⋮----
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external onlyRole(NETWORK_LIMIT_SET_ROLE) {
⋮----
function setOperatorNetworkShares(bytes32 subnetwork, address operator, uint256 shares)
⋮----
function _stakeAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hints)
⋮----
function _stake(bytes32 subnetwork, address operator) internal view override returns (uint256) {
⋮----
function _setMaxNetworkLimit(bytes32 subnetwork, uint256 amount) internal override {
⋮----
function __initialize(address, bytes memory data) internal override returns (IBaseDelegator.BaseParams memory) {
````
## File: src/contracts/delegator/OperatorNetworkSpecificDelegator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseDelegator} from "./BaseDelegator.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
import {Subnetwork} from "../libraries/Subnetwork.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IOperatorNetworkSpecificDelegator} from "../../interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract OperatorNetworkSpecificDelegator is BaseDelegator, IOperatorNetworkSpecificDelegator {
⋮----
/**
* @inheritdoc IOperatorNetworkSpecificDelegator
*/
⋮----
function maxNetworkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function _stakeAt(bytes32 subnetwork, address operator_, uint48 timestamp, bytes memory hints)
⋮----
function _stake(bytes32 subnetwork, address operator_) internal view override returns (uint256) {
⋮----
function _setMaxNetworkLimit(bytes32 subnetwork, uint256 amount) internal override {
⋮----
function __initialize(address, bytes memory data) internal override returns (IBaseDelegator.BaseParams memory) {
````
## File: src/contracts/delegator/OperatorSpecificDelegator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseDelegator} from "./BaseDelegator.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IOperatorSpecificDelegator} from "../../interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract OperatorSpecificDelegator is BaseDelegator, IOperatorSpecificDelegator {
⋮----
/**
* @inheritdoc IOperatorSpecificDelegator
*/
⋮----
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function networkLimit(bytes32 subnetwork) public view returns (uint256) {
⋮----
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external onlyRole(NETWORK_LIMIT_SET_ROLE) {
⋮----
function _stakeAt(bytes32 subnetwork, address operator_, uint48 timestamp, bytes memory hints)
⋮----
function _stake(bytes32 subnetwork, address operator_) internal view override returns (uint256) {
⋮----
function _setMaxNetworkLimit(bytes32 subnetwork, uint256 amount) internal override {
⋮----
function __initialize(address, bytes memory data) internal override returns (IBaseDelegator.BaseParams memory) {
````
## File: src/contracts/hints/DelegatorHints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Hints} from "./Hints.sol";
import {OptInServiceHints} from "./OptInServiceHints.sol";
import {VaultHints} from "./VaultHints.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
import {Subnetwork} from "../libraries/Subnetwork.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IFullRestakeDelegator} from "../../interfaces/delegator/IFullRestakeDelegator.sol";
import {INetworkRestakeDelegator} from "../../interfaces/delegator/INetworkRestakeDelegator.sol";
import {IOperatorNetworkSpecificDelegator} from "../../interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IOperatorSpecificDelegator} from "../../interfaces/delegator/IOperatorSpecificDelegator.sol";
⋮----
contract BaseDelegatorHints is Hints {
⋮----
function stakeHints(address delegator, bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function stakeBaseHints(address delegator, bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
contract NetworkRestakeDelegatorHints is Hints {
⋮----
function networkLimitHintInternal(bytes32 subnetwork, uint48 timestamp)
⋮----
function networkLimitHint(address delegator, bytes32 subnetwork, uint48 timestamp)
⋮----
function operatorNetworkSharesHintInternal(bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function operatorNetworkSharesHint(address delegator, bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function totalOperatorNetworkSharesHintInternal(bytes32 subnetwork, uint48 timestamp)
⋮----
function totalOperatorNetworkSharesHint(address delegator, bytes32 subnetwork, uint48 timestamp)
⋮----
contract FullRestakeDelegatorHints is Hints {
⋮----
function operatorNetworkLimitHintInternal(bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function operatorNetworkLimitHint(address delegator, bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
contract OperatorSpecificDelegatorHints is Hints {
⋮----
function stakeHints(address delegator, bytes32 subnetwork, address operator_, uint48 timestamp)
⋮----
contract OperatorNetworkSpecificDelegatorHints is Hints {
⋮----
function maxNetworkLimitHintInternal(bytes32 subnetwork, uint48 timestamp)
⋮----
function maxNetworkLimitHint(address delegator, bytes32 subnetwork, uint48 timestamp)
````
## File: src/contracts/hints/Hints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IStaticDelegateCallable} from "../../interfaces/common/IStaticDelegateCallable.sol";
⋮----
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
⋮----
abstract contract Hints {
⋮----
modifier internalFunction() {
⋮----
function _selfStaticDelegateCall(address target, bytes memory dataInternal) internal view returns (bytes memory) {
````
## File: src/contracts/hints/OptInServiceHints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Hints} from "./Hints.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
contract OptInServiceHints is Hints {
⋮----
function optInHintInternal(address who, address where, uint48 timestamp)
⋮----
function optInHint(address optInService, address who, address where, uint48 timestamp)
````
## File: src/contracts/hints/SlasherHints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {BaseDelegatorHints} from "./DelegatorHints.sol";
import {Hints} from "./Hints.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IBaseSlasher} from "../../interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../interfaces/slasher/ISlasher.sol";
import {IVaultStorage} from "../../interfaces/vault/IVaultStorage.sol";
import {IVetoSlasher} from "../../interfaces/slasher/IVetoSlasher.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract BaseSlasherHints is Hints {
⋮----
function cumulativeSlashHintInternal(bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function cumulativeSlashHint(address slasher, bytes32 subnetwork, address operator, uint48 timestamp)
⋮----
function slashableStakeHints(address slasher, bytes32 subnetwork, address operator, uint48 captureTimestamp)
⋮----
contract SlasherHints is Hints {
⋮----
function slashHints(address slasher, bytes32 subnetwork, address operator, uint48 captureTimestamp)
⋮----
contract VetoSlasherHints is Hints {
⋮----
function resolverHintInternal(bytes32 subnetwork, uint48 timestamp)
⋮----
function resolverHint(address slasher, bytes32 subnetwork, uint48 timestamp)
⋮----
function requestSlashHints(address slasher, bytes32 subnetwork, address operator, uint48 captureTimestamp)
⋮----
function executeSlashHints(address slasher, uint256 slashIndex) external view returns (bytes memory hints) {
⋮----
function vetoSlashHints(address slasher, uint256 slashIndex) external view returns (bytes memory hints) {
⋮----
function setResolverHints(address slasher, bytes32 subnetwork, uint48 timestamp)
````
## File: src/contracts/hints/VaultHints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Hints} from "./Hints.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
contract VaultHints is Hints {
⋮----
function activeStakeHintInternal(uint48 timestamp)
⋮----
function activeStakeHint(address vault, uint48 timestamp) public view returns (bytes memory hint) {
⋮----
function activeSharesHintInternal(uint48 timestamp)
⋮----
function activeSharesHint(address vault, uint48 timestamp) public view returns (bytes memory hint) {
⋮----
function activeSharesOfHintInternal(address account, uint48 timestamp)
⋮----
function activeSharesOfHint(address vault, address account, uint48 timestamp)
⋮----
function activeBalanceOfHints(address vault, address account, uint48 timestamp)
````
## File: src/contracts/libraries/Checkpoints.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Checkpoints as OZCheckpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
/**
* @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in
* time, and later looking up past values by key.
*/
⋮----
/**
* @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) {
⋮----
/**
* @dev Returns the value in the last (most recent) checkpoint with a key lower or equal than the search key, or zero
* if there is none.
*/
function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {
⋮----
/**
* @dev Returns the value in the last (most recent) checkpoint with a key lower or equal than the search key, or zero
* if there is none.
*
* NOTE: This is a variant of {upperLookupRecent} that can be optimized by getting the hint
* (index of the checkpoint with a key lower or equal than the search key).
*/
function upperLookupRecent(Trace208 storage self, uint48 key, bytes memory hint_) internal view returns (uint208) {
⋮----
/**
* @dev Returns whether there is a checkpoint with a key lower or equal than the search key in the structure (i.e. it is not empty),
* and if so the key and value in the checkpoint, and its position in the trace.
*/
function upperLookupRecentCheckpoint(Trace208 storage self, uint48 key)
⋮----
/**
* @dev Returns whether there is a checkpoint with a key lower or equal than the search key in the structure (i.e. it is not empty),
* and if so the key and value in the checkpoint, and its position in the trace.
*
* NOTE: This is a variant of {upperLookupRecentCheckpoint} that can be optimized by getting the hint
* (index of the checkpoint with a key lower or equal than the search key).
*/
function upperLookupRecentCheckpoint(Trace208 storage self, uint48 key, bytes memory hint_)
⋮----
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(Trace208 storage self) internal view returns (uint208) {
⋮----
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(Trace208 storage self) internal view returns (bool, uint48, uint208) {
⋮----
/**
* @dev Returns a total number of checkpoints.
*/
function length(Trace208 storage self) internal view returns (uint256) {
⋮----
/**
* @dev Returns checkpoint at a given position.
*/
function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {
⋮----
/**
* @dev Pops the last (most recent) checkpoint.
*/
function pop(Trace208 storage self) internal returns (uint208 value) {
⋮----
/**
* @dev Pushes a (`key`, `value`) pair into a Trace256 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(Trace256 storage self, uint48 key, uint256 value) internal returns (uint256, uint256) {
⋮----
function upperLookupRecent(Trace256 storage self, uint48 key) internal view returns (uint256) {
⋮----
function upperLookupRecent(Trace256 storage self, uint48 key, bytes memory hint_) internal view returns (uint256) {
⋮----
function upperLookupRecentCheckpoint(Trace256 storage self, uint48 key)
⋮----
function upperLookupRecentCheckpoint(Trace256 storage self, uint48 key, bytes memory hint_)
⋮----
function latest(Trace256 storage self) internal view returns (uint256) {
⋮----
function latestCheckpoint(Trace256 storage self) internal view returns (bool exists, uint48 _key, uint256 _value) {
⋮----
function length(Trace256 storage self) internal view returns (uint256) {
⋮----
function at(Trace256 storage self, uint32 pos) internal view returns (Checkpoint256 memory) {
⋮----
function pop(Trace256 storage self) internal returns (uint256 value) {
⋮----
/**
* @dev Return the index of the last (most recent) checkpoint with a key lower or equal than the search key, or `high`
* if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive
* `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(OZCheckpoints.Checkpoint208[] storage self, uint48 key, uint256 low, uint256 high)
⋮----
/**
* @dev Access an element of the array without performing a bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(OZCheckpoints.Checkpoint208[] storage self, uint256 pos)
````
## File: src/contracts/libraries/ERC4626Math.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
/**
* @dev This library adds helper functions for ERC4626 math operations.
*/
⋮----
function previewDeposit(uint256 assets, uint256 totalShares, uint256 totalAssets) internal pure returns (uint256) {
⋮----
function previewMint(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
⋮----
function previewWithdraw(uint256 assets, uint256 totalShares, uint256 totalAssets) internal pure returns (uint256) {
⋮----
function previewRedeem(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
⋮----
/**
* @dev Internal conversion function (from assets to shares) with support for rounding direction.
*/
function convertToShares(uint256 assets, uint256 totalShares, uint256 totalAssets, Math.Rounding rounding)
⋮----
/**
* @dev Internal conversion function (from shares to assets) with support for rounding direction.
*/
function convertToAssets(uint256 shares, uint256 totalAssets, uint256 totalShares, Math.Rounding rounding)
⋮----
function _decimalsOffset() private pure returns (uint8) {
````
## File: src/contracts/libraries/LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: src/contracts/libraries/Subnetwork.sol
````
// SPDX-License-Identifier: MIT
⋮----
/**
* @dev This library adds functions to work with subnetworks.
*/
⋮----
function subnetwork(address network_, uint96 identifier_) internal pure returns (bytes32) {
⋮----
function network(bytes32 subnetwork_) internal pure returns (address) {
⋮----
function identifier(bytes32 subnetwork_) internal pure returns (uint96) {
````
## File: src/contracts/service/MetadataService.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {IMetadataService} from "../../interfaces/service/IMetadataService.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
contract MetadataService is IMetadataService {
⋮----
/**
* @inheritdoc IMetadataService
*/
⋮----
function setMetadataURL(string calldata metadataURL_) external {
````
## File: src/contracts/service/NetworkMiddlewareService.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {INetworkMiddlewareService} from "../../interfaces/service/INetworkMiddlewareService.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
⋮----
contract NetworkMiddlewareService is INetworkMiddlewareService {
/**
* @inheritdoc INetworkMiddlewareService
*/
⋮----
function setMiddleware(address middleware_) external {
````
## File: src/contracts/service/OptInService.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {StaticDelegateCallable} from "../common/StaticDelegateCallable.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IOptInService} from "../../interfaces/service/IOptInService.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
⋮----
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract OptInService is StaticDelegateCallable, EIP712, IOptInService {
⋮----
/**
* @inheritdoc IOptInService
*/
⋮----
modifier checkDeadline(uint48 deadline) {
⋮----
function isOptedInAt(address who, address where, uint48 timestamp, bytes calldata hint)
⋮----
function isOptedIn(address who, address where) public view returns (bool) {
⋮----
function optIn(address where) external {
⋮----
function optIn(address who, address where, uint48 deadline, bytes calldata signature)
⋮----
function optOut(address where) external {
⋮----
function optOut(address who, address where, uint48 deadline, bytes calldata signature)
⋮----
function increaseNonce(address where) external {
⋮----
function _optIn(address who, address where) internal {
⋮----
function _optOut(address who, address where) internal {
⋮----
function _hash(bool ifOptIn, address who, address where, uint48 deadline) internal view returns (bytes32) {
⋮----
function _increaseNonce(address who, address where) internal {
````
## File: src/contracts/slasher/BaseSlasher.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Entity} from "../common/Entity.sol";
import {StaticDelegateCallable} from "../common/StaticDelegateCallable.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
import {Subnetwork} from "../libraries/Subnetwork.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "../../interfaces/slasher/IBaseSlasher.sol";
import {IBurner} from "../../interfaces/slasher/IBurner.sol";
import {INetworkMiddlewareService} from "../../interfaces/service/INetworkMiddlewareService.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
abstract contract BaseSlasher is Entity, StaticDelegateCallable, ReentrancyGuardUpgradeable, IBaseSlasher {
⋮----
/**
* @inheritdoc IBaseSlasher
*/
⋮----
modifier onlyNetworkMiddleware(bytes32 subnetwork) {
⋮----
function cumulativeSlashAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
function cumulativeSlash(bytes32 subnetwork, address operator) public view returns (uint256) {
⋮----
function slashableStake(bytes32 subnetwork, address operator, uint48 captureTimestamp, bytes memory hints)
⋮----
function _slashableStake(bytes32 subnetwork, address operator, uint48 captureTimestamp, bytes memory hints)
⋮----
function _checkNetworkMiddleware(bytes32 subnetwork) internal view {
⋮----
function _updateLatestSlashedCaptureTimestamp(bytes32 subnetwork, address operator, uint48 captureTimestamp)
⋮----
function _updateCumulativeSlash(bytes32 subnetwork, address operator, uint256 amount) internal {
⋮----
function _delegatorOnSlash(
⋮----
function _vaultOnSlash(uint256 amount, uint48 captureTimestamp) internal {
⋮----
function _burnerOnSlash(bytes32 subnetwork, address operator, uint256 amount, uint48 captureTimestamp) internal {
⋮----
function _initialize(bytes calldata data) internal override {
⋮----
function __initialize(address vault_, bytes memory data) internal virtual returns (BaseParams memory) {}
````
## File: src/contracts/slasher/Slasher.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseSlasher} from "./BaseSlasher.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../interfaces/slasher/ISlasher.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract Slasher is BaseSlasher, ISlasher {
⋮----
/**
* @inheritdoc ISlasher
*/
function slash(bytes32 subnetwork, address operator, uint256 amount, uint48 captureTimestamp, bytes calldata hints)
⋮----
function __initialize(
⋮----
/* vault_ */
````
## File: src/contracts/slasher/VetoSlasher.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseSlasher} from "./BaseSlasher.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
import {Subnetwork} from "../libraries/Subnetwork.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
import {IVetoSlasher} from "../../interfaces/slasher/IVetoSlasher.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract VetoSlasher is BaseSlasher, IVetoSlasher {
⋮----
/**
* @inheritdoc IVetoSlasher
*/
⋮----
function slashRequestsLength() external view returns (uint256) {
⋮----
function resolverAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) public view returns (address) {
⋮----
function resolver(bytes32 subnetwork, bytes memory hint) public view returns (address) {
⋮----
function requestSlash(
⋮----
function executeSlash(uint256 slashIndex, bytes calldata hints)
⋮----
function vetoSlash(uint256 slashIndex, bytes calldata hints) external nonReentrant {
⋮----
function setResolver(uint96 identifier, address resolver_, bytes calldata hints) external nonReentrant {
⋮----
function __initialize(address vault_, bytes memory data) internal override returns (BaseParams memory) {
````
## File: src/contracts/vault/Vault.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {MigratableEntity} from "../common/MigratableEntity.sol";
import {VaultStorage} from "./VaultStorage.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
import {ERC4626Math} from "../libraries/ERC4626Math.sol";
⋮----
import {IBaseDelegator} from "../../interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "../../interfaces/slasher/IBaseSlasher.sol";
import {IRegistry} from "../../interfaces/common/IRegistry.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVault {
⋮----
/**
* @inheritdoc IVault
*/
function isInitialized() external view returns (bool) {
⋮----
function totalStake() public view returns (uint256) {
⋮----
function activeBalanceOfAt(address account, uint48 timestamp, bytes calldata hints) public view returns (uint256) {
⋮----
function activeBalanceOf(address account) public view returns (uint256) {
⋮----
function withdrawalsOf(uint256 epoch, address account) public view returns (uint256) {
⋮----
function slashableBalanceOf(address account) external view returns (uint256) {
⋮----
function deposit(address onBehalfOf, uint256 amount)
⋮----
function withdraw(address claimer, uint256 amount)
⋮----
function redeem(address claimer, uint256 shares)
⋮----
function claim(address recipient, uint256 epoch) external nonReentrant returns (uint256 amount) {
⋮----
function claimBatch(address recipient, uint256[] calldata epochs) external nonReentrant returns (uint256 amount) {
⋮----
function onSlash(uint256 amount, uint48 captureTimestamp) external nonReentrant returns (uint256 slashedAmount) {
⋮----
function setDepositWhitelist(bool status) external nonReentrant onlyRole(DEPOSIT_WHITELIST_SET_ROLE) {
⋮----
function setDepositorWhitelistStatus(address account, bool status)
⋮----
function setIsDepositLimit(bool status) external nonReentrant onlyRole(IS_DEPOSIT_LIMIT_SET_ROLE) {
⋮----
function setDepositLimit(uint256 limit) external nonReentrant onlyRole(DEPOSIT_LIMIT_SET_ROLE) {
⋮----
function setDelegator(address delegator_) external nonReentrant {
⋮----
function setSlasher(address slasher_) external nonReentrant {
⋮----
function _withdraw(address claimer, uint256 withdrawnAssets, uint256 burnedShares)
⋮----
function _claim(uint256 epoch) internal returns (uint256 amount) {
⋮----
function _initialize(uint64, address, bytes memory data) internal virtual override {
⋮----
function _migrate(
⋮----
/* oldVersion */
⋮----
/* newVersion */
bytes calldata /* data */
````
## File: src/contracts/vault/VaultStorage.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {StaticDelegateCallable} from "../common/StaticDelegateCallable.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IVaultStorage} from "../../interfaces/vault/IVaultStorage.sol";
⋮----
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
abstract contract VaultStorage is StaticDelegateCallable, IVaultStorage {
⋮----
/**
* @inheritdoc IVaultStorage
*/
⋮----
function epochAt(uint48 timestamp) public view returns (uint256) {
⋮----
function currentEpoch() public view returns (uint256) {
⋮----
function currentEpochStart() public view returns (uint48) {
⋮----
function previousEpochStart() public view returns (uint48) {
⋮----
function nextEpochStart() public view returns (uint48) {
⋮----
function activeSharesAt(uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function activeShares() public view returns (uint256) {
⋮----
function activeStakeAt(uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function activeStake() public view returns (uint256) {
⋮----
function activeSharesOfAt(address account, uint48 timestamp, bytes memory hint) public view returns (uint256) {
⋮----
function activeSharesOf(address account) public view returns (uint256) {
````
## File: src/contracts/vault/VaultTokenized.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Vault} from "./Vault.sol";
⋮----
import {Checkpoints} from "../libraries/Checkpoints.sol";
⋮----
import {IVaultTokenized} from "../../interfaces/vault/IVaultTokenized.sol";
import {IVault} from "../../interfaces/vault/IVault.sol";
⋮----
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract VaultTokenized is Vault, ERC20Upgradeable, IVaultTokenized {
⋮----
/**
* @inheritdoc ERC20Upgradeable
*/
function decimals() public view override returns (uint8) {
⋮----
function totalSupply() public view override returns (uint256) {
⋮----
function balanceOf(address account) public view override returns (uint256) {
⋮----
/**
* @inheritdoc IVault
*/
function deposit(address onBehalfOf, uint256 amount)
⋮----
function _withdraw(address claimer, uint256 withdrawnAssets, uint256 burnedShares)
⋮----
function _update(address from, address to, uint256 value) internal override {
⋮----
// Overflow check required: The rest of the code assumes that totalSupply never overflows
⋮----
// Overflow not possible: value <= fromBalance <= totalSupply.
⋮----
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
⋮----
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
⋮----
function _initialize(uint64 initialVersion, address owner_, bytes memory data) internal override {
````
## File: src/contracts/DelegatorFactory.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Factory} from "./common/Factory.sol";
⋮----
import {IDelegatorFactory} from "../interfaces/IDelegatorFactory.sol";
⋮----
contract DelegatorFactory is Factory, IDelegatorFactory {
````
## File: src/contracts/NetworkRegistry.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Registry} from "./common/Registry.sol";
⋮----
import {INetworkRegistry} from "../interfaces/INetworkRegistry.sol";
⋮----
contract NetworkRegistry is Registry, INetworkRegistry {
/**
* @inheritdoc INetworkRegistry
*/
function registerNetwork() external {
````
## File: src/contracts/OperatorRegistry.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Registry} from "./common/Registry.sol";
⋮----
import {IOperatorRegistry} from "../interfaces/IOperatorRegistry.sol";
⋮----
contract OperatorRegistry is Registry, IOperatorRegistry {
/**
* @inheritdoc IOperatorRegistry
*/
function registerOperator() external {
````
## File: src/contracts/SlasherFactory.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Factory} from "./common/Factory.sol";
⋮----
import {ISlasherFactory} from "../interfaces/ISlasherFactory.sol";
⋮----
contract SlasherFactory is Factory, ISlasherFactory {
````
## File: src/contracts/VaultConfigurator.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {BaseSlasher} from "./slasher/BaseSlasher.sol";
import {DelegatorFactory} from "./DelegatorFactory.sol";
import {SlasherFactory} from "./SlasherFactory.sol";
import {VaultFactory} from "./VaultFactory.sol";
import {Vault} from "./vault/Vault.sol";
⋮----
import {IVaultConfigurator} from "../interfaces/IVaultConfigurator.sol";
⋮----
contract VaultConfigurator is IVaultConfigurator {
/**
* @inheritdoc IVaultConfigurator
*/
⋮----
function create(InitParams memory params) public returns (address vault, address delegator, address slasher) {
````
## File: src/contracts/VaultFactory.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {MigratablesFactory} from "./common/MigratablesFactory.sol";
⋮----
import {IVaultFactory} from "../interfaces/IVaultFactory.sol";
⋮----
contract VaultFactory is MigratablesFactory, IVaultFactory {
````
## File: src/interfaces/common/IEntity.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IEntity {
⋮----
/**
* @notice Get the factory's address.
* @return address of the factory
*/
function FACTORY() external view returns (address);
⋮----
/**
* @notice Get the entity's type.
* @return type of the entity
*/
function TYPE() external view returns (uint64);
⋮----
/**
* @notice Initialize this entity contract by using a given data.
* @param data some data to use
*/
function initialize(bytes calldata data) external;
````
## File: src/interfaces/common/IFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry} from "./IRegistry.sol";
⋮----
interface IFactory is IRegistry {
⋮----
/**
* @notice Emitted when a new type is whitelisted.
* @param implementation address of the new implementation
*/
event Whitelist(address indexed implementation);
⋮----
/**
* @notice Emitted when a type is blacklisted (e.g., in case of invalid implementation).
* @param type_ type that was blacklisted
* @dev The given type is still deployable.
*/
event Blacklist(uint64 indexed type_);
⋮----
/**
* @notice Get the total number of whitelisted types.
* @return total number of types
*/
function totalTypes() external view returns (uint64);
⋮----
/**
* @notice Get the implementation for a given type.
* @param type_ position to get the implementation at
* @return address of the implementation
*/
function implementation(uint64 type_) external view returns (address);
⋮----
/**
* @notice Get if a type is blacklisted (e.g., in case of invalid implementation).
* @param type_ type to check
* @return whether the type is blacklisted
* @dev The given type is still deployable.
*/
function blacklisted(uint64 type_) external view returns (bool);
⋮----
/**
* @notice Whitelist a new type of entity.
* @param implementation address of the new implementation
*/
function whitelist(address implementation) external;
⋮----
/**
* @notice Blacklist a type of entity.
* @param type_ type to blacklist
* @dev The given type will still be deployable.
*/
function blacklist(uint64 type_) external;
⋮----
/**
* @notice Create a new entity at the factory.
* @param type_ type's implementation to use
* @param data initial data for the entity creation
* @return address of the entity
* @dev CREATE2 salt is constructed from the given parameters.
*/
function create(uint64 type_, bytes calldata data) external returns (address);
````
## File: src/interfaces/common/IMigratableEntity.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IMigratableEntity {
⋮----
/**
* @notice Get the factory's address.
* @return address of the factory
*/
function FACTORY() external view returns (address);
⋮----
/**
* @notice Get the entity's version.
* @return version of the entity
* @dev Starts from 1.
*/
function version() external view returns (uint64);
⋮----
/**
* @notice Initialize this entity contract by using a given data and setting a particular version and owner.
* @param initialVersion initial version of the entity
* @param owner initial owner of the entity
* @param data some data to use
*/
function initialize(uint64 initialVersion, address owner, bytes calldata data) external;
⋮----
/**
* @notice Migrate this entity to a particular newer version using a given data.
* @param newVersion new version of the entity
* @param data some data to use
*/
function migrate(uint64 newVersion, bytes calldata data) external;
````
## File: src/interfaces/common/IMigratableEntityProxy.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IMigratableEntityProxy {
/**
* @notice Upgrade the proxy to a new implementation and call a function on the new implementation.
* @param newImplementation address of the new implementation
* @param data data to call on the new implementation
*/
function upgradeToAndCall(address newImplementation, bytes calldata data) external;
````
## File: src/interfaces/common/IMigratablesFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry} from "./IRegistry.sol";
⋮----
interface IMigratablesFactory is IRegistry {
⋮----
/**
* @notice Emitted when a new implementation is whitelisted.
* @param implementation address of the new implementation
*/
event Whitelist(address indexed implementation);
⋮----
/**
* @notice Emitted when a version is blacklisted (e.g., in case of invalid implementation).
* @param version version that was blacklisted
* @dev The given version is still deployable.
*/
event Blacklist(uint64 indexed version);
⋮----
/**
* @notice Emitted when an entity is migrated to a new version.
* @param entity address of the entity
* @param newVersion new version of the entity
*/
event Migrate(address indexed entity, uint64 newVersion);
⋮----
/**
* @notice Get the last available version.
* @return version of the last implementation
* @dev If zero, no implementations are whitelisted.
*/
function lastVersion() external view returns (uint64);
⋮----
/**
* @notice Get the implementation for a given version.
* @param version version to get the implementation for
* @return address of the implementation
* @dev Reverts when an invalid version.
*/
function implementation(uint64 version) external view returns (address);
⋮----
/**
* @notice Get if a version is blacklisted (e.g., in case of invalid implementation).
* @param version version to check
* @return whether the version is blacklisted
* @dev The given version is still deployable.
*/
function blacklisted(uint64 version) external view returns (bool);
⋮----
/**
* @notice Whitelist a new implementation for entities.
* @param implementation address of the new implementation
*/
function whitelist(address implementation) external;
⋮----
/**
* @notice Blacklist a version of entities.
* @param version version to blacklist
* @dev The given version will still be deployable.
*/
function blacklist(uint64 version) external;
⋮----
/**
* @notice Create a new entity at the factory.
* @param version entity's version to use
* @param owner initial owner of the entity
* @param data initial data for the entity creation
* @return address of the entity
* @dev CREATE2 salt is constructed from the given parameters.
*/
function create(uint64 version, address owner, bytes calldata data) external returns (address);
⋮----
/**
* @notice Migrate a given entity to a given newer version.
* @param entity address of the entity to migrate
* @param newVersion new version to migrate to
* @param data some data to reinitialize the contract with
* @dev Only the entity's owner can call this function.
*/
function migrate(address entity, uint64 newVersion, bytes calldata data) external;
````
## File: src/interfaces/common/IRegistry.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IRegistry {
⋮----
/**
* @notice Emitted when an entity is added.
* @param entity address of the added entity
*/
event AddEntity(address indexed entity);
⋮----
/**
* @notice Get if a given address is an entity.
* @param account address to check
* @return if the given address is an entity
*/
function isEntity(address account) external view returns (bool);
⋮----
/**
* @notice Get a total number of entities.
* @return total number of entities added
*/
function totalEntities() external view returns (uint256);
⋮----
/**
* @notice Get an entity given its index.
* @param index index of the entity to get
* @return address of the entity
*/
function entity(uint256 index) external view returns (address);
````
## File: src/interfaces/common/IStaticDelegateCallable.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IStaticDelegateCallable {
/**
* @notice Make a delegatecall from this contract to a given target contract with a particular data (always reverts with a return data).
* @param target address of the contract to make a delegatecall to
* @param data data to make a delegatecall with
* @dev It allows to use this contract's storage on-chain.
*/
function staticDelegateCall(address target, bytes calldata data) external;
````
## File: src/interfaces/delegator/IBaseDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IEntity} from "../common/IEntity.sol";
⋮----
interface IBaseDelegator is IEntity {
⋮----
/**
* @notice Base parameters needed for delegators' deployment.
* @param defaultAdminRoleHolder address of the initial DEFAULT_ADMIN_ROLE holder
* @param hook address of the hook contract
* @param hookSetRoleHolder address of the initial HOOK_SET_ROLE holder
*/
⋮----
/**
* @notice Base hints for a stake.
* @param operatorVaultOptInHint hint for the operator-vault opt-in
* @param operatorNetworkOptInHint hint for the operator-network opt-in
*/
⋮----
/**
* @notice Emitted when a subnetwork's maximum limit is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new maximum subnetwork's limit (how much stake the subnetwork is ready to get)
*/
event SetMaxNetworkLimit(bytes32 indexed subnetwork, uint256 amount);
⋮----
/**
* @notice Emitted when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
*/
event OnSlash(bytes32 indexed subnetwork, address indexed operator, uint256 amount, uint48 captureTimestamp);
⋮----
/**
* @notice Emitted when a hook is set.
* @param hook address of the hook
*/
event SetHook(address indexed hook);
⋮----
/**
* @notice Get a version of the delegator (different versions mean different interfaces).
* @return version of the delegator
* @dev Must return 1 for this one.
*/
function VERSION() external view returns (uint64);
⋮----
/**
* @notice Get the network registry's address.
* @return address of the network registry
*/
function NETWORK_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get the vault factory's address.
* @return address of the vault factory
*/
function VAULT_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the operator-vault opt-in service's address.
* @return address of the operator-vault opt-in service
*/
function OPERATOR_VAULT_OPT_IN_SERVICE() external view returns (address);
⋮----
/**
* @notice Get the operator-network opt-in service's address.
* @return address of the operator-network opt-in service
*/
function OPERATOR_NETWORK_OPT_IN_SERVICE() external view returns (address);
⋮----
/**
* @notice Get a gas limit for the hook.
* @return value of the hook gas limit
*/
function HOOK_GAS_LIMIT() external view returns (uint256);
⋮----
/**
* @notice Get a reserve gas between the gas limit check and the hook's execution.
* @return value of the reserve gas
*/
function HOOK_RESERVE() external view returns (uint256);
⋮----
/**
* @notice Get a hook setter's role.
* @return identifier of the hook setter role
*/
function HOOK_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get the vault's address.
* @return address of the vault
*/
function vault() external view returns (address);
⋮----
/**
* @notice Get the hook's address.
* @return address of the hook
* @dev The hook can have arbitrary logic under certain functions, however, it doesn't affect the stake guarantees.
*/
function hook() external view returns (address);
⋮----
/**
* @notice Get a particular subnetwork's maximum limit
* (meaning the subnetwork is not ready to get more as a stake).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @return maximum limit of the subnetwork
*/
function maxNetworkLimit(bytes32 subnetwork) external view returns (uint256);
⋮----
/**
* @notice Get a stake that a given subnetwork could be able to slash for a certain operator at a given timestamp
* until the end of the consequent epoch using hints (if no cross-slashing and no slashings by the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param timestamp time point to capture the stake at
* @param hints hints for the checkpoints' indexes
* @return slashable stake at the given timestamp until the end of the consequent epoch
* @dev Warning: it is not safe to use timestamp >= current one for the stake capturing, as it can change later.
*/
function stakeAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hints)
⋮----
/**
* @notice Get a stake that a given subnetwork will be able to slash
* for a certain operator until the end of the next epoch (if no cross-slashing and no slashings by the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @return slashable stake until the end of the next epoch
* @dev Warning: this function is not safe to use for stake capturing, as it can change by the end of the block.
*/
function stake(bytes32 subnetwork, address operator) external view returns (uint256);
⋮----
/**
* @notice Set a maximum limit for a subnetwork (how much stake the subnetwork is ready to get).
* identifier identifier of the subnetwork
* @param amount new maximum subnetwork's limit
* @dev Only a network can call this function.
*/
function setMaxNetworkLimit(uint96 identifier, uint256 amount) external;
⋮----
/**
* @notice Set a new hook.
* @param hook address of the hook
* @dev Only a HOOK_SET_ROLE holder can call this function.
* The hook can have arbitrary logic under certain functions, however, it doesn't affect the stake guarantees.
*/
function setHook(address hook) external;
⋮----
/**
* @notice Called when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount amount of the collateral slashed
* @param captureTimestamp time point when the stake was captured
* @param data some additional data
* @dev Only the vault's slasher can call this function.
*/
function onSlash(
````
## File: src/interfaces/delegator/IDelegatorHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IDelegatorHook {
/**
* @notice Called when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param data some additional data
*/
function onSlash(
````
## File: src/interfaces/delegator/IFullRestakeDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseDelegator} from "./IBaseDelegator.sol";
⋮----
interface IFullRestakeDelegator is IBaseDelegator {
⋮----
/**
* @notice Hints for a stake.
* @param baseHints base hints
* @param activeStakeHint hint for the active stake checkpoint
* @param networkLimitHint hint for the subnetwork limit checkpoint
* @param operatorNetworkLimitHint hint for the operator-subnetwork limit checkpoint
*/
⋮----
/**
* @notice Initial parameters needed for a full restaking delegator deployment.
* @param baseParams base parameters for delegators' deployment
* @param networkLimitSetRoleHolders array of addresses of the initial NETWORK_LIMIT_SET_ROLE holders
* @param operatorNetworkLimitSetRoleHolders array of addresses of the initial OPERATOR_NETWORK_LIMIT_SET_ROLE holders
*/
⋮----
/**
* @notice Emitted when a subnetwork's limit is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork)
*/
event SetNetworkLimit(bytes32 indexed subnetwork, uint256 amount);
⋮----
/**
* @notice Emitted when an operator's limit for a subnetwork is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount new operator's limit for the subnetwork
* (how much stake the vault curator is ready to give to the operator for the subnetwork)
*/
event SetOperatorNetworkLimit(bytes32 indexed subnetwork, address indexed operator, uint256 amount);
⋮----
/**
* @notice Get a subnetwork limit setter's role.
* @return identifier of the subnetwork limit setter role
*/
function NETWORK_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get an operator-subnetwork limit setter's role.
* @return identifier of the operator-subnetwork limit setter role
*/
function OPERATOR_NETWORK_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get a subnetwork's limit at a given timestamp using a hint
* (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp time point to get the subnetwork limit at
* @param hint hint for checkpoint index
* @return limit of the subnetwork at the given timestamp
*/
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @return limit of the subnetwork
*/
function networkLimit(bytes32 subnetwork) external view returns (uint256);
⋮----
/**
* @notice Get an operator's limit for a subnetwork at a given timestamp using a hint
* (how much stake the vault curator is ready to give to the operator for the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param timestamp time point to get the operator's limit for the subnetwork at
* @param hint hint for checkpoint index
* @return limit of the operator for the subnetwork at the given timestamp
*/
function operatorNetworkLimitAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
/**
* @notice Get an operator's limit for a subnetwork.
* (how much stake the vault curator is ready to give to the operator for the subnetwork)
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @return limit of the operator for the subnetwork
*/
function operatorNetworkLimit(bytes32 subnetwork, address operator) external view returns (uint256);
⋮----
/**
* @notice Set a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new limit of the subnetwork
* @dev Only a NETWORK_LIMIT_SET_ROLE holder can call this function.
*/
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external;
⋮----
/**
* @notice Set an operator's limit for a subnetwork.
* (how much stake the vault curator is ready to give to the operator for the subnetwork)
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount new limit of the operator for the subnetwork
* @dev Only an OPERATOR_NETWORK_LIMIT_SET_ROLE holder can call this function.
*/
function setOperatorNetworkLimit(bytes32 subnetwork, address operator, uint256 amount) external;
````
## File: src/interfaces/delegator/INetworkRestakeDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseDelegator} from "./IBaseDelegator.sol";
⋮----
interface INetworkRestakeDelegator is IBaseDelegator {
⋮----
/**
* @notice Hints for a stake.
* @param baseHints base hints
* @param activeStakeHint hint for the active stake checkpoint
* @param networkLimitHint hint for the subnetwork limit checkpoint
* @param totalOperatorNetworkSharesHint hint for the total operator-subnetwork shares checkpoint
* @param operatorNetworkSharesHint hint for the operator-subnetwork shares checkpoint
*/
⋮----
/**
* @notice Initial parameters needed for a full restaking delegator deployment.
* @param baseParams base parameters for delegators' deployment
* @param networkLimitSetRoleHolders array of addresses of the initial NETWORK_LIMIT_SET_ROLE holders
* @param operatorNetworkSharesSetRoleHolders array of addresses of the initial OPERATOR_NETWORK_SHARES_SET_ROLE holders
*/
⋮----
/**
* @notice Emitted when a subnetwork's limit is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork)
*/
event SetNetworkLimit(bytes32 indexed subnetwork, uint256 amount);
⋮----
/**
* @notice Emitted when an operator's shares inside a subnetwork are set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param shares new operator's shares inside the subnetwork (what percentage,
* which is equal to the shares divided by the total operators' shares,
* of the subnetwork's stake the vault curator is ready to give to the operator)
*/
event SetOperatorNetworkShares(bytes32 indexed subnetwork, address indexed operator, uint256 shares);
⋮----
/**
* @notice Get a subnetwork limit setter's role.
* @return identifier of the subnetwork limit setter role
*/
function NETWORK_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get an operator-subnetwork shares setter's role.
* @return identifier of the operator-subnetwork shares setter role
*/
function OPERATOR_NETWORK_SHARES_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get a subnetwork's limit at a given timestamp using a hint
* (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp time point to get the subnetwork limit at
* @param hint hint for checkpoint index
* @return limit of the subnetwork at the given timestamp
*/
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @return limit of the subnetwork
*/
function networkLimit(bytes32 subnetwork) external view returns (uint256);
⋮----
/**
* @notice Get a sum of operators' shares for a subnetwork at a given timestamp using a hint.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp time point to get the total operators' shares at
* @param hint hint for checkpoint index
* @return total shares of the operators for the subnetwork at the given timestamp
*/
function totalOperatorNetworkSharesAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint)
⋮----
/**
* @notice Get a sum of operators' shares for a subnetwork.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @return total shares of the operators for the subnetwork
*/
function totalOperatorNetworkShares(bytes32 subnetwork) external view returns (uint256);
⋮----
/**
* @notice Get an operator's shares for a subnetwork at a given timestamp using a hint (what percentage,
* which is equal to the shares divided by the total operators' shares,
* of the subnetwork's stake the vault curator is ready to give to the operator).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param timestamp time point to get the operator's shares at
* @param hint hint for checkpoint index
* @return shares of the operator for the subnetwork at the given timestamp
*/
function operatorNetworkSharesAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
/**
* @notice Get an operator's shares for a subnetwork (what percentage,
* which is equal to the shares divided by the total operators' shares,
* of the subnetwork's stake the vault curator is ready to give to the operator).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @return shares of the operator for the subnetwork
*/
function operatorNetworkShares(bytes32 subnetwork, address operator) external view returns (uint256);
⋮----
/**
* @notice Set a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new limit of the subnetwork
* @dev Only a NETWORK_LIMIT_SET_ROLE holder can call this function.
*/
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external;
⋮----
/**
* @notice Set an operator's shares for a subnetwork (what percentage,
* which is equal to the shares divided by the total operators' shares,
* of the subnetwork's stake the vault curator is ready to give to the operator).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param shares new shares of the operator for the subnetwork
* @dev Only an OPERATOR_NETWORK_SHARES_SET_ROLE holder can call this function.
*/
function setOperatorNetworkShares(bytes32 subnetwork, address operator, uint256 shares) external;
````
## File: src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseDelegator} from "./IBaseDelegator.sol";
⋮----
interface IOperatorNetworkSpecificDelegator is IBaseDelegator {
⋮----
/**
* @notice Hints for a stake.
* @param baseHints base hints
* @param activeStakeHint hint for the active stake checkpoint
* @param maxNetworkLimitHint hint for the maximum subnetwork limit checkpoint
*/
⋮----
/**
* @notice Initial parameters needed for an operator-network-specific delegator deployment.
* @param baseParams base parameters for delegators' deployment
* @param network address of the single network
* @param operator address of the single operator
*/
⋮----
/**
* @notice Get the operator registry's address.
* @return address of the operator registry
*/
function OPERATOR_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get a network the vault delegates funds to.
* @return address of the network
*/
function network() external view returns (address);
⋮----
/**
* @notice Get an operator managing the vault's funds.
* @return address of the operator
*/
function operator() external view returns (address);
⋮----
/**
* @notice Get a particular subnetwork's maximum limit at a given timestamp using a hint
* (meaning the subnetwork is not ready to get more as a stake).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp time point to get the maximum subnetwork limit at
* @param hint hint for checkpoint index
* @return maximum limit of the subnetwork
*/
function maxNetworkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) external view returns (uint256);
````
## File: src/interfaces/delegator/IOperatorSpecificDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseDelegator} from "./IBaseDelegator.sol";
⋮----
interface IOperatorSpecificDelegator is IBaseDelegator {
⋮----
/**
* @notice Hints for a stake.
* @param baseHints base hints
* @param activeStakeHint hint for the active stake checkpoint
* @param networkLimitHint hint for the subnetwork limit checkpoint
*/
⋮----
/**
* @notice Initial parameters needed for an operator-specific delegator deployment.
* @param baseParams base parameters for delegators' deployment
* @param networkLimitSetRoleHolders array of addresses of the initial NETWORK_LIMIT_SET_ROLE holders
* @param operator address of the single operator
*/
⋮----
/**
* @notice Emitted when a subnetwork's limit is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork)
*/
event SetNetworkLimit(bytes32 indexed subnetwork, uint256 amount);
⋮----
/**
* @notice Get a subnetwork limit setter's role.
* @return identifier of the subnetwork limit setter role
*/
function NETWORK_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get the operator registry's address.
* @return address of the operator registry
*/
function OPERATOR_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get an operator managing the vault's funds.
* @return address of the operator
*/
function operator() external view returns (address);
⋮----
/**
* @notice Get a subnetwork's limit at a given timestamp using a hint
* (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp time point to get the subnetwork limit at
* @param hint hint for checkpoint index
* @return limit of the subnetwork at the given timestamp
*/
function networkLimitAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @return limit of the subnetwork
*/
function networkLimit(bytes32 subnetwork) external view returns (uint256);
⋮----
/**
* @notice Set a subnetwork's limit (how much stake the vault curator is ready to give to the subnetwork).
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param amount new limit of the subnetwork
* @dev Only a NETWORK_LIMIT_SET_ROLE holder can call this function.
*/
function setNetworkLimit(bytes32 subnetwork, uint256 amount) external;
````
## File: src/interfaces/service/IMetadataService.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IMetadataService {
⋮----
/**
* @notice Emitted when a metadata URL is set for an entity.
* @param entity address of the entity
* @param metadataURL new metadata URL of the entity
*/
event SetMetadataURL(address indexed entity, string metadataURL);
⋮----
/**
* @notice Get the registry's address.
* @return address of the registry
*/
function REGISTRY() external view returns (address);
⋮----
/**
* @notice Get a URL with an entity's metadata.
* @param entity address of the entity
* @return metadata URL of the entity
*/
function metadataURL(address entity) external view returns (string memory);
⋮----
/**
* @notice Set a new metadata URL for a calling entity.
* @param metadataURL new metadata URL of the entity
*/
function setMetadataURL(string calldata metadataURL) external;
````
## File: src/interfaces/service/INetworkMiddlewareService.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface INetworkMiddlewareService {
⋮----
/**
* @notice Emitted when a middleware is set for a network.
* @param network address of the network
* @param middleware new middleware of the network
*/
event SetMiddleware(address indexed network, address middleware);
⋮----
/**
* @notice Get the network registry's address.
* @return address of the network registry
*/
function NETWORK_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get a given network's middleware.
* @param network address of the network
* @return middleware of the network
*/
function middleware(address network) external view returns (address);
⋮----
/**
* @notice Set a new middleware for a calling network.
* @param middleware new middleware of the network
*/
function setMiddleware(address middleware) external;
````
## File: src/interfaces/service/IOptInService.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IOptInService {
⋮----
/**
* @notice Emitted when a "who" opts into a "where" entity.
* @param who address of the "who"
* @param where address of the "where" entity
*/
event OptIn(address indexed who, address indexed where);
⋮----
/**
* @notice Emitted when a "who" opts out from a "where" entity.
* @param who address of the "who"
* @param where address of the "where" entity
*/
event OptOut(address indexed who, address indexed where);
⋮----
/**
* @notice Emitted when the nonce of a "who" to a "where" entity is increased.
* @param who address of the "who"
* @param where address of the "where" entity
*/
event IncreaseNonce(address indexed who, address indexed where);
⋮----
/**
* @notice Get the "who" registry's address.
* @return address of the "who" registry
*/
function WHO_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get the address of the registry where to opt-in.
* @return address of the "where" registry
*/
function WHERE_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get if a given "who" is opted-in to a particular "where" entity at a given timestamp using a hint.
* @param who address of the "who"
* @param where address of the "where" entity
* @param timestamp time point to get if the "who" is opted-in at
* @param hint hint for the checkpoint index
* @return if the "who" is opted-in at the given timestamp
*/
function isOptedInAt(address who, address where, uint48 timestamp, bytes calldata hint) external view returns (bool);
⋮----
/**
* @notice Check if a given "who" is opted-in to a particular "where" entity.
* @param who address of the "who"
* @param where address of the "where" entity
* @return if the "who" is opted-in
*/
function isOptedIn(address who, address where) external view returns (bool);
⋮----
/**
* @notice Get the nonce of a given "who" to a particular "where" entity.
* @param who address of the "who"
* @param where address of the "where" entity
* @return nonce
*/
function nonces(address who, address where) external view returns (uint256);
⋮----
/**
* @notice Opt-in a calling "who" to a particular "where" entity.
* @param where address of the "where" entity
*/
function optIn(address where) external;
⋮----
/**
* @notice Opt-in a "who" to a particular "where" entity with a signature.
* @param who address of the "who"
* @param where address of the "where" entity
* @param deadline time point until the signature is valid (inclusively)
* @param signature signature of the "who"
*/
function optIn(address who, address where, uint48 deadline, bytes calldata signature) external;
⋮----
/**
* @notice Opt-out a calling "who" from a particular "where" entity.
* @param where address of the "where" entity
*/
function optOut(address where) external;
⋮----
/**
* @notice Opt-out a "who" from a particular "where" entity with a signature.
* @param who address of the "who"
* @param where address of the "where" entity
* @param deadline time point until the signature is valid (inclusively)
* @param signature signature of the "who"
*/
function optOut(address who, address where, uint48 deadline, bytes calldata signature) external;
⋮----
/**
* @notice Increase the nonce of a given "who" to a particular "where" entity.
* @param where address of the "where" entity
* @dev It can be used to invalidate a given signature.
*/
function increaseNonce(address where) external;
````
## File: src/interfaces/slasher/IBaseSlasher.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IEntity} from "../common/IEntity.sol";
⋮----
interface IBaseSlasher is IEntity {
⋮----
/**
* @notice Base parameters needed for slashers' deployment.
* @param isBurnerHook if the burner is needed to be called on a slashing
*/
⋮----
/**
* @notice Hints for a slashable stake.
* @param stakeHints hints for the stake checkpoints
* @param cumulativeSlashFromHint hint for the cumulative slash amount at a capture timestamp
*/
⋮----
/**
* @notice General data for the delegator.
* @param slasherType type of the slasher
* @param data slasher-dependent data for the delegator
*/
⋮----
/**
* @notice Get a gas limit for the burner.
* @return value of the burner gas limit
*/
function BURNER_GAS_LIMIT() external view returns (uint256);
⋮----
/**
* @notice Get a reserve gas between the gas limit check and the burner's execution.
* @return value of the reserve gas
*/
function BURNER_RESERVE() external view returns (uint256);
⋮----
/**
* @notice Get the vault factory's address.
* @return address of the vault factory
*/
function VAULT_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the network middleware service's address.
* @return address of the network middleware service
*/
function NETWORK_MIDDLEWARE_SERVICE() external view returns (address);
⋮----
/**
* @notice Get the vault's address.
* @return address of the vault to perform slashings on
*/
function vault() external view returns (address);
⋮----
/**
* @notice Get if the burner is needed to be called on a slashing.
* @return if the burner is a hook
*/
function isBurnerHook() external view returns (bool);
⋮----
/**
* @notice Get the latest capture timestamp that was slashed on a subnetwork.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @return latest capture timestamp that was slashed
*/
function latestSlashedCaptureTimestamp(bytes32 subnetwork, address operator) external view returns (uint48);
⋮----
/**
* @notice Get a cumulative slash amount for an operator on a subnetwork until a given timestamp (inclusively) using a hint.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param timestamp time point to get the cumulative slash amount until (inclusively)
* @param hint hint for the checkpoint index
* @return cumulative slash amount until the given timestamp (inclusively)
*/
function cumulativeSlashAt(bytes32 subnetwork, address operator, uint48 timestamp, bytes memory hint)
⋮----
/**
* @notice Get a cumulative slash amount for an operator on a subnetwork.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @return cumulative slash amount
*/
function cumulativeSlash(bytes32 subnetwork, address operator) external view returns (uint256);
⋮----
/**
* @notice Get a slashable amount of a stake got at a given capture timestamp using hints.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param captureTimestamp time point to get the stake amount at
* @param hints hints for the checkpoints' indexes
* @return slashable amount of the stake
*/
function slashableStake(bytes32 subnetwork, address operator, uint48 captureTimestamp, bytes memory hints)
````
## File: src/interfaces/slasher/IBurner.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IBurner {
/**
* @notice Called when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount virtual amount of the collateral slashed
* @param captureTimestamp time point when the stake was captured
*/
function onSlash(bytes32 subnetwork, address operator, uint256 amount, uint48 captureTimestamp) external;
````
## File: src/interfaces/slasher/ISlasher.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseSlasher} from "./IBaseSlasher.sol";
⋮----
interface ISlasher is IBaseSlasher {
⋮----
/**
* @notice Initial parameters needed for a slasher deployment.
* @param baseParams base parameters for slashers' deployment
*/
⋮----
/**
* @notice Hints for a slash.
* @param slashableStakeHints hints for the slashable stake checkpoints
*/
⋮----
/**
* @notice Extra data for the delegator.
* @param slashableStake amount of the slashable stake before the slash (cache)
* @param stakeAt amount of the stake at the capture time (cache)
*/
⋮----
/**
* @notice Emitted when a slash is performed.
* @param subnetwork subnetwork that requested the slash
* @param operator operator that is slashed
* @param slashedAmount virtual amount of the collateral slashed
* @param captureTimestamp time point when the stake was captured
*/
event Slash(bytes32 indexed subnetwork, address indexed operator, uint256 slashedAmount, uint48 captureTimestamp);
⋮----
/**
* @notice Perform a slash using a subnetwork for a particular operator by a given amount using hints.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount maximum amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param hints hints for checkpoints' indexes
* @return slashedAmount virtual amount of the collateral slashed
* @dev Only a network middleware can call this function.
*/
function slash(bytes32 subnetwork, address operator, uint256 amount, uint48 captureTimestamp, bytes calldata hints)
````
## File: src/interfaces/slasher/IVetoSlasher.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBaseSlasher} from "./IBaseSlasher.sol";
⋮----
interface IVetoSlasher is IBaseSlasher {
⋮----
/**
* @notice Initial parameters needed for a slasher deployment.
* @param baseParams base parameters for slashers' deployment
* @param vetoDuration duration of the veto period for a slash request
* @param resolverSetEpochsDelay delay in epochs for a network to update a resolver
*/
⋮----
/**
* @notice Structure for a slash request.
* @param subnetwork subnetwork that requested the slash
* @param operator operator that could be slashed (if the request is not vetoed)
* @param amount maximum amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param vetoDeadline deadline for the resolver to veto the slash (exclusively)
* @param completed if the slash was vetoed/executed
*/
⋮----
/**
* @notice Hints for a slash request.
* @param slashableStakeHints hints for the slashable stake checkpoints
*/
⋮----
/**
* @notice Hints for a slash execute.
* @param captureResolverHint hint for the resolver checkpoint at the capture time
* @param currentResolverHint hint for the resolver checkpoint at the current time
* @param slashableStakeHints hints for the slashable stake checkpoints
*/
⋮----
/**
* @notice Hints for a slash veto.
* @param captureResolverHint hint for the resolver checkpoint at the capture time
* @param currentResolverHint hint for the resolver checkpoint at the current time
*/
⋮----
/**
* @notice Hints for a resolver set.
* @param resolverHint hint for the resolver checkpoint
*/
⋮----
/**
* @notice Extra data for the delegator.
* @param slashableStake amount of the slashable stake before the slash (cache)
* @param stakeAt amount of the stake at the capture time (cache)
* @param slashIndex index of the slash request
*/
⋮----
/**
* @notice Emitted when a slash request is created.
* @param slashIndex index of the slash request
* @param subnetwork subnetwork that requested the slash
* @param operator operator that could be slashed (if the request is not vetoed)
* @param slashAmount maximum amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param vetoDeadline deadline for the resolver to veto the slash (exclusively)
*/
event RequestSlash(
⋮----
/**
* @notice Emitted when a slash request is executed.
* @param slashIndex index of the slash request
* @param slashedAmount virtual amount of the collateral slashed
*/
event ExecuteSlash(uint256 indexed slashIndex, uint256 slashedAmount);
⋮----
/**
* @notice Emitted when a slash request is vetoed.
* @param slashIndex index of the slash request
* @param resolver address of the resolver that vetoed the slash
*/
event VetoSlash(uint256 indexed slashIndex, address indexed resolver);
⋮----
/**
* @notice Emitted when a resolver is set.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param resolver address of the resolver
*/
event SetResolver(bytes32 indexed subnetwork, address resolver);
⋮----
/**
* @notice Get the network registry's address.
* @return address of the network registry
*/
function NETWORK_REGISTRY() external view returns (address);
⋮----
/**
* @notice Get a duration during which resolvers can veto slash requests.
* @return duration of the veto period
*/
function vetoDuration() external view returns (uint48);
⋮----
/**
* @notice Get a total number of slash requests.
* @return total number of slash requests
*/
function slashRequestsLength() external view returns (uint256);
⋮----
/**
* @notice Get a particular slash request.
* @param slashIndex index of the slash request
* @return subnetwork subnetwork that requested the slash
* @return operator operator that could be slashed (if the request is not vetoed)
* @return amount maximum amount of the collateral to be slashed
* @return captureTimestamp time point when the stake was captured
* @return vetoDeadline deadline for the resolver to veto the slash (exclusively)
* @return completed if the slash was vetoed/executed
*/
function slashRequests(uint256 slashIndex)
⋮----
/**
* @notice Get a delay for networks in epochs to update a resolver.
* @return updating resolver delay in epochs
*/
function resolverSetEpochsDelay() external view returns (uint256);
⋮----
/**
* @notice Get a resolver for a given subnetwork at a particular timestamp using a hint.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param timestamp timestamp to get the resolver at
* @param hint hint for the checkpoint index
* @return address of the resolver
*/
function resolverAt(bytes32 subnetwork, uint48 timestamp, bytes memory hint) external view returns (address);
⋮----
/**
* @notice Get a resolver for a given subnetwork using a hint.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param hint hint for the checkpoint index
* @return address of the resolver
*/
function resolver(bytes32 subnetwork, bytes memory hint) external view returns (address);
⋮----
/**
* @notice Request a slash using a subnetwork for a particular operator by a given amount using hints.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param amount maximum amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param hints hints for checkpoints' indexes
* @return slashIndex index of the slash request
* @dev Only a network middleware can call this function.
*/
function requestSlash(
⋮----
/**
* @notice Execute a slash with a given slash index using hints.
* @param slashIndex index of the slash request
* @param hints hints for checkpoints' indexes
* @return slashedAmount virtual amount of the collateral slashed
* @dev Only a network middleware can call this function.
*/
function executeSlash(uint256 slashIndex, bytes calldata hints) external returns (uint256 slashedAmount);
⋮----
/**
* @notice Veto a slash with a given slash index using hints.
* @param slashIndex index of the slash request
* @param hints hints for checkpoints' indexes
* @dev Only a resolver can call this function.
*/
function vetoSlash(uint256 slashIndex, bytes calldata hints) external;
⋮----
/**
* @notice Set a resolver for a subnetwork using hints.
* identifier identifier of the subnetwork
* @param resolver address of the resolver
* @param hints hints for checkpoints' indexes
* @dev Only a network can call this function.
*/
function setResolver(uint96 identifier, address resolver, bytes calldata hints) external;
````
## File: src/interfaces/vault/IVault.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IMigratableEntity} from "../common/IMigratableEntity.sol";
import {IVaultStorage} from "./IVaultStorage.sol";
⋮----
interface IVault is IMigratableEntity, IVaultStorage {
⋮----
/**
* @notice Initial parameters needed for a vault deployment.
* @param collateral vault's underlying collateral
* @param burner vault's burner to issue debt to (e.g., 0xdEaD or some unwrapper contract)
* @param epochDuration duration of the vault epoch (it determines sync points for withdrawals)
* @param depositWhitelist if enabling deposit whitelist
* @param isDepositLimit if enabling deposit limit
* @param depositLimit deposit limit (maximum amount of the collateral that can be in the vault simultaneously)
* @param defaultAdminRoleHolder address of the initial DEFAULT_ADMIN_ROLE holder
* @param depositWhitelistSetRoleHolder address of the initial DEPOSIT_WHITELIST_SET_ROLE holder
* @param depositorWhitelistRoleHolder address of the initial DEPOSITOR_WHITELIST_ROLE holder
* @param isDepositLimitSetRoleHolder address of the initial IS_DEPOSIT_LIMIT_SET_ROLE holder
* @param depositLimitSetRoleHolder address of the initial DEPOSIT_LIMIT_SET_ROLE holder
*/
⋮----
/**
* @notice Hints for an active balance.
* @param activeSharesOfHint hint for the active shares of checkpoint
* @param activeStakeHint hint for the active stake checkpoint
* @param activeSharesHint hint for the active shares checkpoint
*/
⋮----
/**
* @notice Emitted when a deposit is made.
* @param depositor account that made the deposit
* @param onBehalfOf account the deposit was made on behalf of
* @param amount amount of the collateral deposited
* @param shares amount of the active shares minted
*/
event Deposit(address indexed depositor, address indexed onBehalfOf, uint256 amount, uint256 shares);
⋮----
/**
* @notice Emitted when a withdrawal is made.
* @param withdrawer account that made the withdrawal
* @param claimer account that needs to claim the withdrawal
* @param amount amount of the collateral withdrawn
* @param burnedShares amount of the active shares burned
* @param mintedShares amount of the epoch withdrawal shares minted
*/
event Withdraw(
⋮----
/**
* @notice Emitted when a claim is made.
* @param claimer account that claimed
* @param recipient account that received the collateral
* @param epoch epoch the collateral was claimed for
* @param amount amount of the collateral claimed
*/
event Claim(address indexed claimer, address indexed recipient, uint256 epoch, uint256 amount);
⋮----
/**
* @notice Emitted when a batch claim is made.
* @param claimer account that claimed
* @param recipient account that received the collateral
* @param epochs epochs the collateral was claimed for
* @param amount amount of the collateral claimed
*/
event ClaimBatch(address indexed claimer, address indexed recipient, uint256[] epochs, uint256 amount);
⋮----
/**
* @notice Emitted when a slash happens.
* @param amount amount of the collateral to slash
* @param captureTimestamp time point when the stake was captured
* @param slashedAmount real amount of the collateral slashed
*/
event OnSlash(uint256 amount, uint48 captureTimestamp, uint256 slashedAmount);
⋮----
/**
* @notice Emitted when a deposit whitelist status is enabled/disabled.
* @param status if enabled deposit whitelist
*/
event SetDepositWhitelist(bool status);
⋮----
/**
* @notice Emitted when a depositor whitelist status is set.
* @param account account for which the whitelist status is set
* @param status if whitelisted the account
*/
event SetDepositorWhitelistStatus(address indexed account, bool status);
⋮----
/**
* @notice Emitted when a deposit limit status is enabled/disabled.
* @param status if enabled deposit limit
*/
event SetIsDepositLimit(bool status);
⋮----
/**
* @notice Emitted when a deposit limit is set.
* @param limit deposit limit (maximum amount of the collateral that can be in the vault simultaneously)
*/
event SetDepositLimit(uint256 limit);
⋮----
/**
* @notice Emitted when a delegator is set.
* @param delegator vault's delegator to delegate the stake to networks and operators
* @dev Can be set only once.
*/
event SetDelegator(address indexed delegator);
⋮----
/**
* @notice Emitted when a slasher is set.
* @param slasher vault's slasher to provide a slashing mechanism to networks
* @dev Can be set only once.
*/
event SetSlasher(address indexed slasher);
⋮----
/**
* @notice Check if the vault is fully initialized (a delegator and a slasher are set).
* @return if the vault is fully initialized
*/
function isInitialized() external view returns (bool);
⋮----
/**
* @notice Get a total amount of the collateral that can be slashed.
* @return total amount of the slashable collateral
*/
function totalStake() external view returns (uint256);
⋮----
/**
* @notice Get an active balance for a particular account at a given timestamp using hints.
* @param account account to get the active balance for
* @param timestamp time point to get the active balance for the account at
* @param hints hints for checkpoints' indexes
* @return active balance for the account at the timestamp
*/
function activeBalanceOfAt(address account, uint48 timestamp, bytes calldata hints) external view returns (uint256);
⋮----
/**
* @notice Get an active balance for a particular account.
* @param account account to get the active balance for
* @return active balance for the account
*/
function activeBalanceOf(address account) external view returns (uint256);
⋮----
/**
* @notice Get withdrawals for a particular account at a given epoch (zero if claimed).
* @param epoch epoch to get the withdrawals for the account at
* @param account account to get the withdrawals for
* @return withdrawals for the account at the epoch
*/
function withdrawalsOf(uint256 epoch, address account) external view returns (uint256);
⋮----
/**
* @notice Get a total amount of the collateral that can be slashed for a given account.
* @param account account to get the slashable collateral for
* @return total amount of the account's slashable collateral
*/
function slashableBalanceOf(address account) external view returns (uint256);
⋮----
/**
* @notice Deposit collateral into the vault.
* @param onBehalfOf account the deposit is made on behalf of
* @param amount amount of the collateral to deposit
* @return depositedAmount real amount of the collateral deposited
* @return mintedShares amount of the active shares minted
*/
function deposit(address onBehalfOf, uint256 amount)
⋮----
/**
* @notice Withdraw collateral from the vault (it will be claimable after the next epoch).
* @param claimer account that needs to claim the withdrawal
* @param amount amount of the collateral to withdraw
* @return burnedShares amount of the active shares burned
* @return mintedShares amount of the epoch withdrawal shares minted
*/
function withdraw(address claimer, uint256 amount) external returns (uint256 burnedShares, uint256 mintedShares);
⋮----
/**
* @notice Redeem collateral from the vault (it will be claimable after the next epoch).
* @param claimer account that needs to claim the withdrawal
* @param shares amount of the active shares to redeem
* @return withdrawnAssets amount of the collateral withdrawn
* @return mintedShares amount of the epoch withdrawal shares minted
*/
function redeem(address claimer, uint256 shares) external returns (uint256 withdrawnAssets, uint256 mintedShares);
⋮----
/**
* @notice Claim collateral from the vault.
* @param recipient account that receives the collateral
* @param epoch epoch to claim the collateral for
* @return amount amount of the collateral claimed
*/
function claim(address recipient, uint256 epoch) external returns (uint256 amount);
⋮----
/**
* @notice Claim collateral from the vault for multiple epochs.
* @param recipient account that receives the collateral
* @param epochs epochs to claim the collateral for
* @return amount amount of the collateral claimed
*/
function claimBatch(address recipient, uint256[] calldata epochs) external returns (uint256 amount);
⋮----
/**
* @notice Slash callback for burning collateral.
* @param amount amount to slash
* @param captureTimestamp time point when the stake was captured
* @return slashedAmount real amount of the collateral slashed
* @dev Only the slasher can call this function.
*/
function onSlash(uint256 amount, uint48 captureTimestamp) external returns (uint256 slashedAmount);
⋮----
/**
* @notice Enable/disable deposit whitelist.
* @param status if enabling deposit whitelist
* @dev Only a DEPOSIT_WHITELIST_SET_ROLE holder can call this function.
*/
function setDepositWhitelist(bool status) external;
⋮----
/**
* @notice Set a depositor whitelist status.
* @param account account for which the whitelist status is set
* @param status if whitelisting the account
* @dev Only a DEPOSITOR_WHITELIST_ROLE holder can call this function.
*/
function setDepositorWhitelistStatus(address account, bool status) external;
⋮----
/**
* @notice Enable/disable deposit limit.
* @param status if enabling deposit limit
* @dev Only a IS_DEPOSIT_LIMIT_SET_ROLE holder can call this function.
*/
function setIsDepositLimit(bool status) external;
⋮----
/**
* @notice Set a deposit limit.
* @param limit deposit limit (maximum amount of the collateral that can be in the vault simultaneously)
* @dev Only a DEPOSIT_LIMIT_SET_ROLE holder can call this function.
*/
function setDepositLimit(uint256 limit) external;
⋮----
/**
* @notice Set a delegator.
* @param delegator vault's delegator to delegate the stake to networks and operators
* @dev Can be set only once.
*/
function setDelegator(address delegator) external;
⋮----
/**
* @notice Set a slasher.
* @param slasher vault's slasher to provide a slashing mechanism to networks
* @dev Can be set only once.
*/
function setSlasher(address slasher) external;
````
## File: src/interfaces/vault/IVaultStorage.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IVaultStorage {
⋮----
/**
* @notice Get a deposit whitelist enabler/disabler's role.
* @return identifier of the whitelist enabler/disabler role
*/
function DEPOSIT_WHITELIST_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get a depositor whitelist status setter's role.
* @return identifier of the depositor whitelist status setter role
*/
function DEPOSITOR_WHITELIST_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get a deposit limit enabler/disabler's role.
* @return identifier of the deposit limit enabler/disabler role
*/
function IS_DEPOSIT_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get a deposit limit setter's role.
* @return identifier of the deposit limit setter role
*/
function DEPOSIT_LIMIT_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get the delegator factory's address.
* @return address of the delegator factory
*/
function DELEGATOR_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the slasher factory's address.
* @return address of the slasher factory
*/
function SLASHER_FACTORY() external view returns (address);
⋮----
/**
* @notice Get a vault collateral.
* @return address of the underlying collateral
*/
function collateral() external view returns (address);
⋮----
/**
* @notice Get a burner to issue debt to (e.g., 0xdEaD or some unwrapper contract).
* @return address of the burner
*/
function burner() external view returns (address);
⋮----
/**
* @notice Get a delegator (it delegates the vault's stake to networks and operators).
* @return address of the delegator
*/
function delegator() external view returns (address);
⋮----
/**
* @notice Get if the delegator is initialized.
* @return if the delegator is initialized
*/
function isDelegatorInitialized() external view returns (bool);
⋮----
/**
* @notice Get a slasher (it provides networks a slashing mechanism).
* @return address of the slasher
*/
function slasher() external view returns (address);
⋮----
/**
* @notice Get if the slasher is initialized.
* @return if the slasher is initialized
*/
function isSlasherInitialized() external view returns (bool);
⋮----
/**
* @notice Get a time point of the epoch duration set.
* @return time point of the epoch duration set
*/
function epochDurationInit() external view returns (uint48);
⋮----
/**
* @notice Get a duration of the vault epoch.
* @return duration of the epoch
*/
function epochDuration() external view returns (uint48);
⋮----
/**
* @notice Get an epoch at a given timestamp.
* @param timestamp time point to get the epoch at
* @return epoch at the timestamp
* @dev Reverts if the timestamp is less than the start of the epoch 0.
*/
function epochAt(uint48 timestamp) external view returns (uint256);
⋮----
/**
* @notice Get a current vault epoch.
* @return current epoch
*/
function currentEpoch() external view returns (uint256);
⋮----
/**
* @notice Get a start of the current vault epoch.
* @return start of the current epoch
*/
function currentEpochStart() external view returns (uint48);
⋮----
/**
* @notice Get a start of the previous vault epoch.
* @return start of the previous epoch
* @dev Reverts if the current epoch is 0.
*/
function previousEpochStart() external view returns (uint48);
⋮----
/**
* @notice Get a start of the next vault epoch.
* @return start of the next epoch
*/
function nextEpochStart() external view returns (uint48);
⋮----
/**
* @notice Get if the deposit whitelist is enabled.
* @return if the deposit whitelist is enabled
*/
function depositWhitelist() external view returns (bool);
⋮----
/**
* @notice Get if a given account is whitelisted as a depositor.
* @param account address to check
* @return if the account is whitelisted as a depositor
*/
function isDepositorWhitelisted(address account) external view returns (bool);
⋮----
/**
* @notice Get if the deposit limit is set.
* @return if the deposit limit is set
*/
function isDepositLimit() external view returns (bool);
⋮----
/**
* @notice Get a deposit limit (maximum amount of the active stake that can be in the vault simultaneously).
* @return deposit limit
*/
function depositLimit() external view returns (uint256);
⋮----
/**
* @notice Get a total number of active shares in the vault at a given timestamp using a hint.
* @param timestamp time point to get the total number of active shares at
* @param hint hint for the checkpoint index
* @return total number of active shares at the timestamp
*/
function activeSharesAt(uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a total number of active shares in the vault.
* @return total number of active shares
*/
function activeShares() external view returns (uint256);
⋮----
/**
* @notice Get a total amount of active stake in the vault at a given timestamp using a hint.
* @param timestamp time point to get the total active stake at
* @param hint hint for the checkpoint index
* @return total amount of active stake at the timestamp
*/
function activeStakeAt(uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a total amount of active stake in the vault.
* @return total amount of active stake
*/
function activeStake() external view returns (uint256);
⋮----
/**
* @notice Get a total number of active shares for a particular account at a given timestamp using a hint.
* @param account account to get the number of active shares for
* @param timestamp time point to get the number of active shares for the account at
* @param hint hint for the checkpoint index
* @return number of active shares for the account at the timestamp
*/
function activeSharesOfAt(address account, uint48 timestamp, bytes memory hint) external view returns (uint256);
⋮----
/**
* @notice Get a number of active shares for a particular account.
* @param account account to get the number of active shares for
* @return number of active shares for the account
*/
function activeSharesOf(address account) external view returns (uint256);
⋮----
/**
* @notice Get a total amount of the withdrawals at a given epoch.
* @param epoch epoch to get the total amount of the withdrawals at
* @return total amount of the withdrawals at the epoch
*/
function withdrawals(uint256 epoch) external view returns (uint256);
⋮----
/**
* @notice Get a total number of withdrawal shares at a given epoch.
* @param epoch epoch to get the total number of withdrawal shares at
* @return total number of withdrawal shares at the epoch
*/
function withdrawalShares(uint256 epoch) external view returns (uint256);
⋮----
/**
* @notice Get a number of withdrawal shares for a particular account at a given epoch (zero if claimed).
* @param epoch epoch to get the number of withdrawal shares for the account at
* @param account account to get the number of withdrawal shares for
* @return number of withdrawal shares for the account at the epoch
*/
function withdrawalSharesOf(uint256 epoch, address account) external view returns (uint256);
⋮----
/**
* @notice Get if the withdrawals are claimed for a particular account at a given epoch.
* @param epoch epoch to check the withdrawals for the account at
* @param account account to check the withdrawals for
* @return if the withdrawals are claimed for the account at the epoch
*/
function isWithdrawalsClaimed(uint256 epoch, address account) external view returns (bool);
````
## File: src/interfaces/vault/IVaultTokenized.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IVault} from "./IVault.sol";
⋮----
interface IVaultTokenized is IVault {
/**
* @notice Initial parameters needed for a tokenized vault deployment.
* @param baseParams initial parameters needed for a vault deployment (InitParams)
* @param name name for the ERC20 tokenized vault
* @param symbol symbol for the ERC20 tokenized vault
*/
````
## File: src/interfaces/IDelegatorFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFactory} from "./common/IFactory.sol";
⋮----
interface IDelegatorFactory is IFactory {}
````
## File: src/interfaces/INetworkRegistry.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry} from "./common/IRegistry.sol";
⋮----
interface INetworkRegistry is IRegistry {
⋮----
/**
* @notice Register the caller as a network.
*/
function registerNetwork() external;
````
## File: src/interfaces/IOperatorRegistry.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry} from "./common/IRegistry.sol";
⋮----
interface IOperatorRegistry is IRegistry {
⋮----
/**
* @notice Register the caller as an operator.
*/
function registerOperator() external;
````
## File: src/interfaces/ISlasherFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFactory} from "./common/IFactory.sol";
⋮----
interface ISlasherFactory is IFactory {}
````
## File: src/interfaces/IVaultConfigurator.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IVaultConfigurator {
/**
* @notice Initial parameters needed for a vault with a delegator and a slasher deployment.
* @param version entity's version to use
* @param owner initial owner of the entity
* @param vaultParams parameters for the vault initialization
* @param delegatorIndex delegator's index of the implementation to deploy
* @param delegatorParams parameters for the delegator initialization
* @param withSlasher whether to deploy a slasher or not
* @param slasherIndex slasher's index of the implementation to deploy (used only if withSlasher == true)
* @param slasherParams parameters for the slasher initialization (used only if withSlasher == true)
*/
⋮----
/**
* @notice Get the vault factory's address.
* @return address of the vault factory
*/
function VAULT_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the delegator factory's address.
* @return address of the delegator factory
*/
function DELEGATOR_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the slasher factory's address.
* @return address of the slasher factory
*/
function SLASHER_FACTORY() external view returns (address);
⋮----
/**
* @notice Create a new vault with a delegator and a slasher.
* @param params initial parameters needed for a vault with a delegator and a slasher deployment
* @return vault address of the vault
* @return delegator address of the delegator
* @return slasher address of the slasher
*/
function create(InitParams calldata params) external returns (address vault, address delegator, address slasher);
````
## File: src/interfaces/IVaultFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IMigratablesFactory} from "./common/IMigratablesFactory.sol";
⋮----
interface IVaultFactory is IMigratablesFactory {}
````
## File: src/interfaces/LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: test/common/Entity.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {Factory} from "../../src/contracts/common/Factory.sol";
import {IFactory} from "../../src/interfaces/common/IFactory.sol";
⋮----
import {IEntity} from "../../src/interfaces/common/IEntity.sol";
⋮----
import {SimpleEntity} from "../mocks/SimpleEntity.sol";
⋮----
contract EntityTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/common/Factory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {Factory} from "../../src/contracts/common/Factory.sol";
import {IFactory} from "../../src/interfaces/common/IFactory.sol";
⋮----
import {IEntity} from "../../src/interfaces/common/IEntity.sol";
⋮----
import {SimpleEntity} from "../mocks/SimpleEntity.sol";
import {FakeEntity} from "../mocks/FakeEntity.sol";
⋮----
contract FactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_CreateRevertInvalidIndex() public {
⋮----
function test_WhitelistRevertInvalidImplementation1() public {
⋮----
function test_WhitelistRevertInvalidImplementation2() public {
⋮----
function test_WhitelistRevertAlreadyWhitelisted() public {
⋮----
function test_BlacklistRevertAlreadyBlacklisted() public {
⋮----
function test_BlacklistRevertIinvalidType() public {
````
## File: test/common/MigratableEntity.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {IRegistry} from "../../src/interfaces/common/IRegistry.sol";
⋮----
import {MigratablesFactory} from "../../src/contracts/common/MigratablesFactory.sol";
import {IMigratablesFactory} from "../../src/interfaces/common/IMigratablesFactory.sol";
import {IMigratableEntityProxy} from "../../src/interfaces/common/IMigratableEntityProxy.sol";
⋮----
import {IMigratableEntity} from "../../src/interfaces/common/IMigratableEntity.sol";
⋮----
import {MigratableEntityProxy} from "../../src/contracts/common/MigratableEntityProxy.sol";
⋮----
import {SimpleMigratableEntity} from "../mocks/SimpleMigratableEntity.sol";
import {SimpleMigratableEntityV2} from "../mocks/SimpleMigratableEntityV2.sol";
⋮----
contract MigratableEntityTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_ReinitRevertAlreadyInitialized() public {
⋮----
function test_Migrate(uint256 a1, uint256 a2, uint256 b1, uint256 b2) public {
⋮----
function test_MigrateRevertNotFactory() public {
````
## File: test/common/MigratableEntityProxy.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {IRegistry} from "../../src/interfaces/common/IRegistry.sol";
⋮----
import {MigratablesFactory} from "../../src/contracts/common/MigratablesFactory.sol";
import {IMigratablesFactory} from "../../src/interfaces/common/IMigratablesFactory.sol";
⋮----
import {IMigratableEntity} from "../../src/interfaces/common/IMigratableEntity.sol";
⋮----
import {MigratableEntityProxy} from "../../src/contracts/common/MigratableEntityProxy.sol";
⋮----
import {SimpleMigratableEntity} from "../mocks/SimpleMigratableEntity.sol";
import {SimpleMigratableEntityV2} from "../mocks/SimpleMigratableEntityV2.sol";
⋮----
contract MigratableEntityProxyTest is Test {
⋮----
function setUp() public {
⋮----
function test_MigrateRevertProxyDeniedAdminAccess() public {
````
## File: test/common/MigratablesFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {IRegistry} from "../../src/interfaces/common/IRegistry.sol";
⋮----
import {MigratablesFactory} from "../../src/contracts/common/MigratablesFactory.sol";
import {IMigratablesFactory} from "../../src/interfaces/common/IMigratablesFactory.sol";
⋮----
import {SimpleMigratableEntity} from "../mocks/SimpleMigratableEntity.sol";
import {SimpleMigratableEntityV2} from "../mocks/SimpleMigratableEntityV2.sol";
⋮----
contract MigratablesFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_CreateRevertInvalidVersion() public {
⋮----
function test_Migrate(uint256 a) public {
⋮----
function test_MigrateRevertImproperOwner() public {
⋮----
function test_MigrateRevertInvalidVersion() public {
⋮----
function test_MigrateRevertOldVersion() public {
⋮----
function test_WhitelistRevertInvalidImplementation() public {
⋮----
function test_WhitelistRevertAlreadyWhitelisted() public {
⋮----
function test_BlacklistRevertAlreadyBlacklisted() public {
⋮----
function test_BlacklistRevertInvalidVersion() public {
````
## File: test/common/Registry.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {SimpleRegistry} from "../mocks/SimpleRegistry.sol";
⋮----
contract FactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/delegator/FullRestakeDelegator.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SimpleFullRestakeDelegatorHook} from "../mocks/SimpleFullRestakeDelegatorHook.sol";
⋮----
import {BaseDelegatorHints, FullRestakeDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract FullRestakeDelegatorTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoleHolders(uint48 epochDuration) public {
⋮----
function test_CreateRevertZeroAddressRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertZeroAddressRoleHolder2(uint48 epochDuration) public {
⋮----
function test_CreateRevertDuplicateRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertDuplicateRoleHolder2(uint48 epochDuration) public {
⋮----
function test_OnSlashRevertNotSlasher(uint48 epochDuration) public {
⋮----
function test_SetNetworkLimit(
⋮----
function test_SetNetworkLimitRevertExceedsMaxNetworkLimit(
⋮----
function test_SetNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 amount1, uint256 maxNetworkLimit)
⋮----
function test_SetOperatorNetworkLimit(
⋮----
function test_SetOperatorNetworkLimitBoth(uint48 epochDuration, uint256 amount1, uint256 amount2, uint256 amount3)
⋮----
function test_SetOperatorNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 amount1) public {
⋮----
function test_SetMaxNetworkLimit(
⋮----
function test_SetMaxNetworkLimitRevertNotNetwork(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_SetMaxNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_Stakes(
⋮----
function test_Slash(
⋮----
function test_SlashWithHookBase(
// uint48 epochDuration,
⋮----
// uint256 networkLimit,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// networkLimit = bound(networkLimit, 1, type(uint256).max);
⋮----
function test_SlashWithHookGas(
⋮----
function test_SetHook(uint48 epochDuration) public {
⋮----
function test_SetHookRevertAlreadySet(uint48 epochDuration) public {
⋮----
// function test_NetworkLimitHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration);
⋮----
// address network = alice;
// _registerNetwork(network, alice);
// _setMaxNetworkLimit(network, 0, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _setNetworkLimit(alice, network, amount1 + i);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// OptInServiceHints optInServiceHints = new OptInServiceHints();
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
// FullRestakeDelegatorHints fullRestakeDelegatorHints =
// FullRestakeDelegatorHints(baseDelegatorHints.FULL_RESTAKE_DELEGATOR_HINTS());
// bytes memory hint =
// fullRestakeDelegatorHints.networkLimitHint(address(delegator), network.subnetwork(0), timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// delegator.networkLimitAt(network.subnetwork(0), timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// delegator.networkLimitAt(network.subnetwork(0), timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
// }
⋮----
// function test_OperatorNetworkLimitHint(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct
// ) public {
⋮----
// _setOperatorNetworkLimit(alice, network, alice, amount1);
⋮----
// fullRestakeDelegatorHints.operatorNetworkLimitHint(address(delegator), network, alice, timestamp);
⋮----
// delegator.operatorNetworkLimitAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.operatorNetworkLimitAt(network, alice, timestamp, hint);
⋮----
// struct StakeBaseHintsUint32 {
// bool withOperatorVaultOptInHint;
// uint32 operatorVaultOptInHint;
// bool withOperatorNetworkOptInHint;
// uint32 operatorNetworkOptInHint;
⋮----
// function test_StakeBaseHints(
⋮----
// HintStruct memory hintStruct,
// StakeBaseHintsUint32 memory stakeBaseHintsUint32
⋮----
// if (stakeBaseHintsUint32.withOperatorVaultOptInHint) {
// stakeBaseHintsUint32.operatorVaultOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeBaseHintsUint32.withOperatorNetworkOptInHint) {
// stakeBaseHintsUint32.operatorNetworkOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// _registerOperator(alice);
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// bytes memory hints = baseDelegatorHints.stakeBaseHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeBaseHintsUint32.withOperatorVaultOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeBaseHintsUint32.withOperatorNetworkOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
// try baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, stakeBaseHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, new bytes(0));
⋮----
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, hints);
⋮----
// struct StakeHintsUint32 {
// bool withBaseHints;
// StakeBaseHintsUint32 baseHints;
// bool withActiveStakeHint;
// uint32 activeStakeHint;
// bool withNetworkLimitHint;
// uint32 networkLimitHint;
// bool withOperatorNetworkLimitHint;
// uint32 operatorNetworkLimitHint;
⋮----
// function test_StakeHints(
⋮----
// StakeHintsUint32 memory stakeHintsUint32
⋮----
// if (stakeHintsUint32.baseHints.withOperatorVaultOptInHint) {
// stakeHintsUint32.baseHints.operatorVaultOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.baseHints.withOperatorNetworkOptInHint) {
// stakeHintsUint32.baseHints.operatorNetworkOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withActiveStakeHint) {
// stakeHintsUint32.activeStakeHint = uint32(bound(stakeHintsUint32.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withNetworkLimitHint) {
// stakeHintsUint32.networkLimitHint = uint32(bound(stakeHintsUint32.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withOperatorNetworkLimitHint) {
// stakeHintsUint32.operatorNetworkLimitHint =
// uint32(bound(stakeHintsUint32.operatorNetworkLimitHint, 0, 10 * hintStruct.num));
⋮----
// bytes memory hints = fullRestakeDelegatorHints.stakeHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints;
// if (stakeHintsUint32.withBaseHints) {
// stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeHintsUint32.baseHints.withOperatorVaultOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeHintsUint32.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
⋮----
// bytes memory stakeHints = abi.encode(
// IFullRestakeDelegator.StakeHints({
// baseHints: stakeBaseHints,
// activeStakeHint: stakeHintsUint32.withActiveStakeHint
// ? abi.encode(stakeHintsUint32.activeStakeHint)
⋮----
// networkLimitHint: stakeHintsUint32.withNetworkLimitHint
// ? abi.encode(stakeHintsUint32.networkLimitHint)
⋮----
// operatorNetworkLimitHint: stakeHintsUint32.withOperatorNetworkLimitHint
// ? abi.encode(stakeHintsUint32.operatorNetworkLimitHint)
⋮----
// try delegator.stakeAt(network, alice, timestamp, stakeHints) {
⋮----
// delegator.stakeAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.stakeAt(network, alice, timestamp, hints);
⋮----
// function test_BaseStakeHints(
⋮----
// bytes memory hints = baseDelegatorHints.stakeHints(address(delegator), network, alice, timestamp);
⋮----
// struct OnSlashHintsUint32 {
// bool withHints;
// StakeHintsUint32 hints;
⋮----
// function test_OnSlashHints(
⋮----
// OnSlashHintsUint32 memory onSlashHintsUint32
⋮----
// amount1 = bound(amount1, 1, 10 * 10 ** 18);
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withActiveStakeHint) {
// onSlashHintsUint32.hints.activeStakeHint =
// uint32(bound(onSlashHintsUint32.hints.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withNetworkLimitHint) {
// onSlashHintsUint32.hints.networkLimitHint =
// uint32(bound(onSlashHintsUint32.hints.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withOperatorNetworkLimitHint) {
// onSlashHintsUint32.hints.operatorNetworkLimitHint =
// uint32(bound(onSlashHintsUint32.hints.operatorNetworkLimitHint, 0, 10 * hintStruct.num));
⋮----
// // address network = alice;
// _registerNetwork(alice, alice);
// _setMaxNetworkLimit(alice, type(uint256).max);
⋮----
// _optInOperatorNetwork(alice, address(alice));
⋮----
// _deposit(alice, amount1);
// _setNetworkLimit(alice, alice, amount1);
// _setOperatorNetworkLimit(alice, alice, alice, amount1);
⋮----
// _optOutOperatorNetwork(alice, address(alice));
⋮----
// baseDelegatorHints = new BaseDelegatorHints(address(new OptInServiceHints()), address(new VaultHints()));
⋮----
// bytes memory stakeHints;
// if (onSlashHintsUint32.withHints) {
// stakeHints = abi.encode(
// IFullRestakeDelegator.StakeHints({
// baseHints: onSlashHintsUint32.hints.withBaseHints
// ? abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// )
⋮----
// activeStakeHint: onSlashHintsUint32.hints.withActiveStakeHint
// ? abi.encode(onSlashHintsUint32.hints.activeStakeHint)
⋮----
// networkLimitHint: onSlashHintsUint32.hints.withNetworkLimitHint
// ? abi.encode(onSlashHintsUint32.hints.networkLimitHint)
⋮----
// operatorNetworkLimitHint: onSlashHintsUint32.hints.withOperatorNetworkLimitHint
// ? abi.encode(onSlashHintsUint32.hints.operatorNetworkLimitHint)
⋮----
// try baseDelegatorHints._onSlash(
// address(delegator),
// alice,
⋮----
// amount1,
// timestamp,
// abi.encode(IBaseDelegator.OnSlashHints({stakeHints: stakeHints}))
// ) {
⋮----
// baseDelegatorHints._onSlash(address(delegator), alice, alice, amount1, timestamp, new bytes(0));
⋮----
// bytes memory hints = baseDelegatorHints.onSlashHints(address(delegator), alice, alice, amount1, timestamp);
// baseDelegatorHints._onSlash(address(delegator), alice, alice, amount1, timestamp, hints);
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, FullRestakeDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getSlasher(address vault_) internal returns (Slasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkLimit(address user, address network, address operator, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
function _setHook(address user, address hook) internal {
````
## File: test/delegator/NetworkRestakeDelegator.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SimpleNetworkRestakeDelegatorHook} from "../mocks/SimpleNetworkRestakeDelegatorHook.sol";
⋮----
import {BaseDelegatorHints, NetworkRestakeDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract NetworkRestakeDelegatorTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoleHolders(uint48 epochDuration) public {
⋮----
function test_CreateRevertZeroAddressRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertZeroAddressRoleHolder2(uint48 epochDuration) public {
⋮----
function test_CreateRevertDuplicateRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertDuplicateRoleHolder2(uint48 epochDuration) public {
⋮----
function test_OnSlashRevertNotSlasher(uint48 epochDuration) public {
⋮----
function test_SetNetworkLimit(
⋮----
function test_SetNetworkLimitRevertExceedsMaxNetworkLimit(
⋮----
function test_SetNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 amount1, uint256 maxNetworkLimit)
⋮----
function test_SetOperatorNetworkSharesBoth(uint48 epochDuration, uint256 amount1, uint256 amount2, uint256 amount3)
⋮----
function test_SetOperatorNetworkSharesRevertAlreadySet(uint48 epochDuration, uint256 amount1) public {
⋮----
function test_SetMaxNetworkLimit(
⋮----
function test_SetMaxNetworkLimitRevertNotNetwork(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_SetMaxNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_Stakes(
⋮----
function test_SlashBase(
⋮----
// address network = alice;
⋮----
function test_SlashWithHookBase(
// uint48 epochDuration,
⋮----
// uint256 networkLimit,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// networkLimit = bound(networkLimit, 1, type(uint256).max);
⋮----
function test_SlashWithHookGas(
⋮----
function test_SetHook(uint48 epochDuration) public {
⋮----
function test_SetHookRevertAlreadySet(uint48 epochDuration) public {
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_NetworkLimitHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration);
⋮----
// address network = alice;
// _registerNetwork(network, alice);
// _setMaxNetworkLimit(network, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _setNetworkLimit(alice, network, amount1);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// OptInServiceHints optInServiceHints = new OptInServiceHints();
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
// NetworkRestakeDelegatorHints networkRestakeDelegatorHints =
// NetworkRestakeDelegatorHints(baseDelegatorHints.NETWORK_RESTAKE_DELEGATOR_HINTS());
// bytes memory hint = networkRestakeDelegatorHints.networkLimitHint(address(delegator), network, timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// delegator.networkLimitAt(network, timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// delegator.networkLimitAt(network, timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// function test_OperatorNetworkSharesHint(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct
// ) public {
⋮----
// _setOperatorNetworkShares(alice, network, alice, amount1);
⋮----
// bytes memory hint =
// networkRestakeDelegatorHints.operatorNetworkSharesHint(address(delegator), network, alice, timestamp);
⋮----
// delegator.operatorNetworkSharesAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.operatorNetworkSharesAt(network, alice, timestamp, hint);
⋮----
// function test_TotalOperatorNetworkSharesHint(
⋮----
// networkRestakeDelegatorHints.totalOperatorNetworkSharesHint(address(delegator), network, timestamp);
⋮----
// delegator.totalOperatorNetworkSharesAt(network, timestamp, new bytes(0));
⋮----
// delegator.totalOperatorNetworkSharesAt(network, timestamp, hint);
⋮----
// struct StakeBaseHintsUint32 {
// bool withOperatorVaultOptInHint;
// uint32 operatorVaultOptInHint;
// bool withOperatorNetworkOptInHint;
// uint32 operatorNetworkOptInHint;
⋮----
// function test_StakeBaseHints(
⋮----
// HintStruct memory hintStruct,
// StakeBaseHintsUint32 memory stakeBaseHintsUint32
⋮----
// if (stakeBaseHintsUint32.withOperatorVaultOptInHint) {
// stakeBaseHintsUint32.operatorVaultOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeBaseHintsUint32.withOperatorNetworkOptInHint) {
// stakeBaseHintsUint32.operatorNetworkOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// _registerOperator(alice);
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// bytes memory hints = baseDelegatorHints.stakeBaseHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeBaseHintsUint32.withOperatorVaultOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeBaseHintsUint32.withOperatorNetworkOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
// try baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, stakeBaseHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, new bytes(0));
⋮----
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, hints);
⋮----
// struct StakeHintsUint32 {
// bool withBaseHints;
// StakeBaseHintsUint32 baseHints;
// bool withActiveStakeHint;
// uint32 activeStakeHint;
// bool withNetworkLimitHint;
// uint32 networkLimitHint;
// bool withOperatorNetworkSharesHint;
// uint32 operatorNetworkSharesHint;
// bool withTotalOperatorNetworkSharesHint;
// uint32 totalOperatorNetworkSharesHint;
⋮----
// function test_StakeHints(
⋮----
// StakeHintsUint32 memory stakeHintsUint32
⋮----
// if (stakeHintsUint32.baseHints.withOperatorVaultOptInHint) {
// stakeHintsUint32.baseHints.operatorVaultOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.baseHints.withOperatorNetworkOptInHint) {
// stakeHintsUint32.baseHints.operatorNetworkOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withActiveStakeHint) {
// stakeHintsUint32.activeStakeHint = uint32(bound(stakeHintsUint32.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withNetworkLimitHint) {
// stakeHintsUint32.networkLimitHint = uint32(bound(stakeHintsUint32.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withOperatorNetworkSharesHint) {
// stakeHintsUint32.operatorNetworkSharesHint =
// uint32(bound(stakeHintsUint32.operatorNetworkSharesHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withTotalOperatorNetworkSharesHint) {
// stakeHintsUint32.totalOperatorNetworkSharesHint =
// uint32(bound(stakeHintsUint32.totalOperatorNetworkSharesHint, 0, 10 * hintStruct.num));
⋮----
// bytes memory hints = networkRestakeDelegatorHints.stakeHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints;
// if (stakeHintsUint32.withBaseHints) {
// stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeHintsUint32.baseHints.withOperatorVaultOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeHintsUint32.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
⋮----
// bytes memory stakeHints = abi.encode(
// INetworkRestakeDelegator.StakeHints({
// baseHints: stakeBaseHints,
// activeStakeHint: stakeHintsUint32.withActiveStakeHint
// ? abi.encode(stakeHintsUint32.activeStakeHint)
⋮----
// networkLimitHint: stakeHintsUint32.withNetworkLimitHint
// ? abi.encode(stakeHintsUint32.networkLimitHint)
⋮----
// operatorNetworkSharesHint: stakeHintsUint32.withOperatorNetworkSharesHint
// ? abi.encode(stakeHintsUint32.operatorNetworkSharesHint)
⋮----
// totalOperatorNetworkSharesHint: stakeHintsUint32.withTotalOperatorNetworkSharesHint
// ? abi.encode(stakeHintsUint32.totalOperatorNetworkSharesHint)
⋮----
// try delegator.stakeAt(network, alice, timestamp, stakeHints) {
⋮----
// delegator.stakeAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.stakeAt(network, alice, timestamp, hints);
⋮----
// function test_BaseStakeHints(
⋮----
// struct OnSlashHintsUint32 {
// bool withHints;
// StakeHintsUint32 hints;
⋮----
// function test_OnSlashHints(
⋮----
// OnSlashHintsUint32 memory onSlashHintsUint32
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withActiveStakeHint) {
// onSlashHintsUint32.hints.activeStakeHint =
// uint32(bound(onSlashHintsUint32.hints.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withNetworkLimitHint) {
// onSlashHintsUint32.hints.networkLimitHint =
// uint32(bound(onSlashHintsUint32.hints.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withOperatorNetworkSharesHint) {
// onSlashHintsUint32.hints.operatorNetworkSharesHint =
// uint32(bound(onSlashHintsUint32.hints.operatorNetworkSharesHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withTotalOperatorNetworkSharesHint) {
// onSlashHintsUint32.hints.totalOperatorNetworkSharesHint =
// uint32(bound(onSlashHintsUint32.hints.totalOperatorNetworkSharesHint, 0, 10 * hintStruct.num));
⋮----
// baseDelegatorHints = new BaseDelegatorHints(address(new OptInServiceHints()), address(new VaultHints()));
⋮----
// bytes memory stakeHints;
// if (onSlashHintsUint32.withHints) {
// stakeHints = abi.encode(
// INetworkRestakeDelegator.StakeHints({
// baseHints: onSlashHintsUint32.hints.withBaseHints
// ? abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// )
⋮----
// activeStakeHint: onSlashHintsUint32.hints.withActiveStakeHint
// ? abi.encode(onSlashHintsUint32.hints.activeStakeHint)
⋮----
// networkLimitHint: onSlashHintsUint32.hints.withNetworkLimitHint
// ? abi.encode(onSlashHintsUint32.hints.networkLimitHint)
⋮----
// operatorNetworkSharesHint: onSlashHintsUint32.hints.withOperatorNetworkSharesHint
// ? abi.encode(onSlashHintsUint32.hints.operatorNetworkSharesHint)
⋮----
// totalOperatorNetworkSharesHint: onSlashHintsUint32.hints.withTotalOperatorNetworkSharesHint
// ? abi.encode(onSlashHintsUint32.hints.totalOperatorNetworkSharesHint)
⋮----
// try baseDelegatorHints._onSlash(
// address(delegator),
// network,
// alice,
// amount1,
// timestamp,
// abi.encode(IBaseDelegator.OnSlashHints({stakeHints: stakeHints}))
// ) {
⋮----
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, new bytes(0));
⋮----
// bytes memory hints = baseDelegatorHints.onSlashHints(address(delegator), network, alice, amount1, timestamp);
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, hints);
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, NetworkRestakeDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getSlasher(address vault_) internal returns (Slasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkShares(address user, address network, address operator, uint256 shares) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
function _setHook(address user, address hook) internal {
````
## File: test/delegator/OperatorNetworkSpecificDelegator.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {IOperatorNetworkSpecificDelegator} from "../../src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SimpleOperatorNetworkSpecificDelegatorHook} from "../mocks/SimpleOperatorNetworkSpecificDelegatorHook.sol";
⋮----
import {BaseDelegatorHints, OperatorNetworkSpecificDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract OperatorNetworkSpecificDelegatorTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotNetwork(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotOperator(uint48 epochDuration) public {
⋮----
function test_OnSlashRevertNotSlasher(uint48 epochDuration) public {
⋮----
function test_SetMaxNetworkLimit(
⋮----
function test_SetMaxNetworkLimitRevertNotNetwork(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_SetMaxNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_SetMaxNetworkLimitRevertInvalidNetwork(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_Stakes(
⋮----
function test_SlashBase(
⋮----
// address network = bob;
⋮----
function test_SlashWithHook(
// uint48 epochDuration,
⋮----
// uint256 networkLimit,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// networkLimit = bound(networkLimit, 1, type(uint256).max);
⋮----
function test_SlashWithHookGas(
⋮----
function test_SetHook(uint48 epochDuration) public {
⋮----
function test_SetHookRevertAlreadySet(uint48 epochDuration) public {
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_MaxNetworkLimitHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = block.timestamp * block.timestamp / block.timestamp * block.timestamp / block.timestamp;
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration);
⋮----
// address network = alice;
// _registerNetwork(network, alice);
// _setMaxNetworkLimit(network, 0, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _setMaxNetworkLimit(network, 0, amount1);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// OptInServiceHints optInServiceHints = new OptInServiceHints();
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
// OperatorNetworkSpecificDelegatorHints OperatorNetworkSpecificDelegatorHints =
// OperatorNetworkSpecificDelegatorHints(baseDelegatorHints.NETWORK_RESTAKE_DELEGATOR_HINTS());
// bytes memory hint = OperatorNetworkSpecificDelegatorHints.maxNetworkLimitHint(address(delegator), network, timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// delegator.maxNetworkLimitAt(network, timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// delegator.maxNetworkLimitAt(network, timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// struct StakeBaseHintsUint32 {
// bool withOperatorVaultOptInHint;
// uint32 operatorVaultOptInHint;
// bool withOperatorNetworkOptInHint;
// uint32 operatorNetworkOptInHint;
⋮----
// function test_StakeBaseHints(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct,
// StakeBaseHintsUint32 memory stakeBaseHintsUint32
// ) public {
⋮----
// if (stakeBaseHintsUint32.withOperatorVaultOptInHint) {
// stakeBaseHintsUint32.operatorVaultOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeBaseHintsUint32.withOperatorNetworkOptInHint) {
// stakeBaseHintsUint32.operatorNetworkOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// _registerOperator(alice);
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// bytes memory hints = baseDelegatorHints.stakeBaseHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeBaseHintsUint32.withOperatorVaultOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeBaseHintsUint32.withOperatorNetworkOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
// try baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, stakeBaseHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, new bytes(0));
⋮----
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, hints);
⋮----
// struct StakeHintsUint32 {
// bool withBaseHints;
// StakeBaseHintsUint32 baseHints;
// bool withActiveStakeHint;
// uint32 activeStakeHint;
// bool withNetworkLimitHint;
// uint32 maxNetworkLimitHint;
⋮----
// function test_StakeHints(
⋮----
// StakeHintsUint32 memory stakeHintsUint32
⋮----
// if (stakeHintsUint32.baseHints.withOperatorVaultOptInHint) {
// stakeHintsUint32.baseHints.operatorVaultOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.baseHints.withOperatorNetworkOptInHint) {
// stakeHintsUint32.baseHints.operatorNetworkOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withActiveStakeHint) {
// stakeHintsUint32.activeStakeHint = uint32(bound(stakeHintsUint32.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withNetworkLimitHint) {
// stakeHintsUint32.maxNetworkLimitHint = uint32(bound(stakeHintsUint32.maxNetworkLimitHint, 0, 10 * hintStruct.num));
⋮----
// bytes memory hints = OperatorNetworkSpecificDelegatorHints.stakeHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints;
// if (stakeHintsUint32.withBaseHints) {
// stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeHintsUint32.baseHints.withOperatorVaultOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeHintsUint32.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
⋮----
// bytes memory stakeHints = abi.encode(
// IOperatorNetworkSpecificDelegator.StakeHints({
// baseHints: stakeBaseHints,
// activeStakeHint: stakeHintsUint32.withActiveStakeHint
// ? abi.encode(stakeHintsUint32.activeStakeHint)
⋮----
// maxNetworkLimitHint: stakeHintsUint32.withNetworkLimitHint
// ? abi.encode(stakeHintsUint32.maxNetworkLimitHint)
⋮----
// try delegator.stakeAt(network, alice, timestamp, stakeHints) {
⋮----
// delegator.stakeAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.stakeAt(network, alice, timestamp, hints);
⋮----
// function test_BaseStakeHints(
⋮----
// struct OnSlashHintsUint32 {
// bool withHints;
// StakeHintsUint32 hints;
⋮----
// function test_OnSlashHints(
⋮----
// OnSlashHintsUint32 memory onSlashHintsUint32
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withActiveStakeHint) {
// onSlashHintsUint32.hints.activeStakeHint =
// uint32(bound(onSlashHintsUint32.hints.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withNetworkLimitHint) {
// onSlashHintsUint32.hints.maxNetworkLimitHint =
// uint32(bound(onSlashHintsUint32.hints.maxNetworkLimitHint, 0, 10 * hintStruct.num));
⋮----
// baseDelegatorHints = new BaseDelegatorHints(address(new OptInServiceHints()), address(new VaultHints()));
⋮----
// bytes memory stakeHints;
// if (onSlashHintsUint32.withHints) {
// stakeHints = abi.encode(
// IOperatorNetworkSpecificDelegator.StakeHints({
// baseHints: onSlashHintsUint32.hints.withBaseHints
// ? abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// )
⋮----
// activeStakeHint: onSlashHintsUint32.hints.withActiveStakeHint
// ? abi.encode(onSlashHintsUint32.hints.activeStakeHint)
⋮----
// maxNetworkLimitHint: onSlashHintsUint32.hints.withNetworkLimitHint
// ? abi.encode(onSlashHintsUint32.hints.maxNetworkLimitHint)
⋮----
// try baseDelegatorHints._onSlash(
// address(delegator),
// network,
// alice,
// amount1,
// timestamp,
// abi.encode(IBaseDelegator.OnSlashHints({stakeHints: stakeHints}))
// ) {
⋮----
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, new bytes(0));
⋮----
// bytes memory hints = baseDelegatorHints.onSlashHints(address(delegator), network, alice, amount1, timestamp);
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, hints);
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, OperatorNetworkSpecificDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getSlasher(address vault_) internal returns (Slasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
function _setHook(address user, address hook) internal {
````
## File: test/delegator/OperatorSpecificDelegator.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {IOperatorSpecificDelegator} from "../../src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {SimpleOperatorSpecificDelegatorHook} from "../mocks/SimpleOperatorSpecificDelegatorHook.sol";
⋮----
import {BaseDelegatorHints, OperatorSpecificDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract OperatorSpecificDelegatorTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoleHolders(uint48 epochDuration) public {
⋮----
function test_CreateRevertZeroAddressRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertDuplicateRoleHolder1(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotOperator(uint48 epochDuration) public {
⋮----
function test_OnSlashRevertNotSlasher(uint48 epochDuration) public {
⋮----
function test_SetNetworkLimit(
⋮----
function test_SetNetworkLimitRevertExceedsMaxNetworkLimit(
⋮----
function test_SetNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 amount1, uint256 maxNetworkLimit)
⋮----
function test_SetMaxNetworkLimit(
⋮----
function test_SetMaxNetworkLimitRevertNotNetwork(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_SetMaxNetworkLimitRevertAlreadySet(uint48 epochDuration, uint256 maxNetworkLimit) public {
⋮----
function test_Stakes(
⋮----
function test_SlashBase(
⋮----
// address network = alice;
⋮----
function test_SlashWithHook(
// uint48 epochDuration,
⋮----
// uint256 networkLimit,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// networkLimit = bound(networkLimit, 1, type(uint256).max);
⋮----
function test_SlashWithHookGas(
⋮----
function test_SetHook(uint48 epochDuration) public {
⋮----
function test_SetHookRevertAlreadySet(uint48 epochDuration) public {
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_NetworkLimitHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration);
⋮----
// address network = alice;
// _registerNetwork(network, alice);
// _setMaxNetworkLimit(network, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _setNetworkLimit(alice, network, amount1);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// OptInServiceHints optInServiceHints = new OptInServiceHints();
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
// OperatorSpecificDelegatorHints OperatorSpecificDelegatorHints =
// OperatorSpecificDelegatorHints(baseDelegatorHints.NETWORK_RESTAKE_DELEGATOR_HINTS());
// bytes memory hint = OperatorSpecificDelegatorHints.networkLimitHint(address(delegator), network, timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// delegator.networkLimitAt(network, timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// delegator.networkLimitAt(network, timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// struct StakeBaseHintsUint32 {
// bool withOperatorVaultOptInHint;
// uint32 operatorVaultOptInHint;
// bool withOperatorNetworkOptInHint;
// uint32 operatorNetworkOptInHint;
⋮----
// function test_StakeBaseHints(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct,
// StakeBaseHintsUint32 memory stakeBaseHintsUint32
// ) public {
⋮----
// if (stakeBaseHintsUint32.withOperatorVaultOptInHint) {
// stakeBaseHintsUint32.operatorVaultOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeBaseHintsUint32.withOperatorNetworkOptInHint) {
// stakeBaseHintsUint32.operatorNetworkOptInHint =
// uint32(bound(stakeBaseHintsUint32.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// _registerOperator(alice);
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// bytes memory hints = baseDelegatorHints.stakeBaseHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeBaseHintsUint32.withOperatorVaultOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeBaseHintsUint32.withOperatorNetworkOptInHint
// ? abi.encode(stakeBaseHintsUint32.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
// try baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, stakeBaseHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, new bytes(0));
⋮----
// baseDelegatorHints._stakeBaseHints(address(delegator), network, alice, timestamp, hints);
⋮----
// struct StakeHintsUint32 {
// bool withBaseHints;
// StakeBaseHintsUint32 baseHints;
// bool withActiveStakeHint;
// uint32 activeStakeHint;
// bool withNetworkLimitHint;
// uint32 networkLimitHint;
⋮----
// function test_StakeHints(
⋮----
// StakeHintsUint32 memory stakeHintsUint32
⋮----
// if (stakeHintsUint32.baseHints.withOperatorVaultOptInHint) {
// stakeHintsUint32.baseHints.operatorVaultOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.baseHints.withOperatorNetworkOptInHint) {
// stakeHintsUint32.baseHints.operatorNetworkOptInHint =
// uint32(bound(stakeHintsUint32.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withActiveStakeHint) {
// stakeHintsUint32.activeStakeHint = uint32(bound(stakeHintsUint32.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (stakeHintsUint32.withNetworkLimitHint) {
// stakeHintsUint32.networkLimitHint = uint32(bound(stakeHintsUint32.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// bytes memory hints = OperatorSpecificDelegatorHints.stakeHints(address(delegator), network, alice, timestamp);
⋮----
// bytes memory stakeBaseHints;
// if (stakeHintsUint32.withBaseHints) {
// stakeBaseHints = abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: stakeHintsUint32.baseHints.withOperatorVaultOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: stakeHintsUint32.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(stakeHintsUint32.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// );
⋮----
// bytes memory stakeHints = abi.encode(
// IOperatorSpecificDelegator.StakeHints({
// baseHints: stakeBaseHints,
// activeStakeHint: stakeHintsUint32.withActiveStakeHint
// ? abi.encode(stakeHintsUint32.activeStakeHint)
⋮----
// networkLimitHint: stakeHintsUint32.withNetworkLimitHint
// ? abi.encode(stakeHintsUint32.networkLimitHint)
⋮----
// try delegator.stakeAt(network, alice, timestamp, stakeHints) {
⋮----
// delegator.stakeAt(network, alice, timestamp, new bytes(0));
⋮----
// delegator.stakeAt(network, alice, timestamp, hints);
⋮----
// function test_BaseStakeHints(
⋮----
// struct OnSlashHintsUint32 {
// bool withHints;
// StakeHintsUint32 hints;
⋮----
// function test_OnSlashHints(
⋮----
// OnSlashHintsUint32 memory onSlashHintsUint32
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint) {
// onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint =
// uint32(bound(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withActiveStakeHint) {
// onSlashHintsUint32.hints.activeStakeHint =
// uint32(bound(onSlashHintsUint32.hints.activeStakeHint, 0, 10 * hintStruct.num));
⋮----
// if (onSlashHintsUint32.hints.withNetworkLimitHint) {
// onSlashHintsUint32.hints.networkLimitHint =
// uint32(bound(onSlashHintsUint32.hints.networkLimitHint, 0, 10 * hintStruct.num));
⋮----
// baseDelegatorHints = new BaseDelegatorHints(address(new OptInServiceHints()), address(new VaultHints()));
⋮----
// bytes memory stakeHints;
// if (onSlashHintsUint32.withHints) {
// stakeHints = abi.encode(
// IOperatorSpecificDelegator.StakeHints({
// baseHints: onSlashHintsUint32.hints.withBaseHints
// ? abi.encode(
// IBaseDelegator.StakeBaseHints({
// operatorVaultOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorVaultOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorVaultOptInHint)
// : new bytes(0),
// operatorNetworkOptInHint: onSlashHintsUint32.hints.baseHints.withOperatorNetworkOptInHint
// ? abi.encode(onSlashHintsUint32.hints.baseHints.operatorNetworkOptInHint)
// : new bytes(0)
// })
// )
⋮----
// activeStakeHint: onSlashHintsUint32.hints.withActiveStakeHint
// ? abi.encode(onSlashHintsUint32.hints.activeStakeHint)
⋮----
// networkLimitHint: onSlashHintsUint32.hints.withNetworkLimitHint
// ? abi.encode(onSlashHintsUint32.hints.networkLimitHint)
⋮----
// try baseDelegatorHints._onSlash(
// address(delegator),
// network,
// alice,
// amount1,
// timestamp,
// abi.encode(IBaseDelegator.OnSlashHints({stakeHints: stakeHints}))
// ) {
⋮----
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, new bytes(0));
⋮----
// bytes memory hints = baseDelegatorHints.onSlashHints(address(delegator), network, alice, amount1, timestamp);
// baseDelegatorHints._onSlash(address(delegator), network, alice, amount1, timestamp, hints);
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, OperatorSpecificDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getSlasher(address vault_) internal returns (Slasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
function _setHook(address user, address hook) internal {
````
## File: test/integration/actions/ActionScripts.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "../SymbioticCoreInit.sol";
import "../base/SymbioticCoreInitBase.sol";
import {Subnetwork} from "../../../src/contracts/libraries/Subnetwork.sol";
⋮----
import {IVault} from "../../../src/interfaces/vault/IVault.sol";
import {IFullRestakeDelegator} from "../../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {INetworkRestakeDelegator} from "../../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseDelegator} from "../../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "../../../src/interfaces/slasher/IVetoSlasher.sol";
import {IEntity} from "../../../src/interfaces/common/IEntity.sol";
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
⋮----
import {ScriptBase} from "../../../script/utils/ScriptBase.s.sol";
import {ScriptBaseHarness} from "./ScriptBaseHarness.s.sol";
⋮----
import {OptInNetworkBaseScript} from "../../../script/actions/base/OptInNetworkBase.s.sol";
import {OptInVaultBaseScript} from "../../../script/actions/base/OptInVaultBase.s.sol";
import {RegisterOperatorBaseScript} from "../../../script/actions/base/RegisterOperatorBase.s.sol";
import {SetHookBaseScript} from "../../../script/actions/base/SetHookBase.s.sol";
import {SetMaxNetworkLimitBaseScript} from "../../../script/actions/base/SetMaxNetworkLimitBase.s.sol";
import {SetNetworkLimitBaseScript} from "../../../script/actions/base/SetNetworkLimitBase.s.sol";
import {SetOperatorNetworkSharesBaseScript} from "../../../script/actions/base/SetOperatorNetworkSharesBase.s.sol";
import {SetResolverBaseScript} from "../../../script/actions/base/SetResolverBase.s.sol";
import {VetoSlashBaseScript} from "../../../script/actions/base/VetoSlashBase.s.sol";
⋮----
interface IVetoSlasherExtended is IVetoSlasher {
function slashRequests(uint256 index)
⋮----
contract RegisterOperatorScriptHarness is RegisterOperatorBaseScript, ScriptBaseHarness {
⋮----
function sendTransaction(address target, bytes memory data) public override(ScriptBase, ScriptBaseHarness) {
⋮----
contract OptInVaultScriptHarness is OptInVaultBaseScript, ScriptBaseHarness {
⋮----
contract OptInNetworkScriptHarness is OptInNetworkBaseScript, ScriptBaseHarness {
⋮----
contract SetHookScriptHarness is SetHookBaseScript, ScriptBaseHarness {
⋮----
contract SetMaxNetworkLimitScriptHarness is SetMaxNetworkLimitBaseScript, ScriptBaseHarness {
⋮----
contract SetNetworkLimitScriptHarness is SetNetworkLimitBaseScript, ScriptBaseHarness {
⋮----
contract SetOperatorNetworkSharesScriptHarness is SetOperatorNetworkSharesBaseScript, ScriptBaseHarness {
⋮----
contract SetResolverScriptHarness is SetResolverBaseScript, ScriptBaseHarness {
⋮----
contract VetoSlashScriptHarness is VetoSlashBaseScript, ScriptBaseHarness {
⋮----
contract ActionScriptsTest is SymbioticCoreInit {
⋮----
function setUp() public virtual override {
⋮----
// Let _getVault_SymbioticCore handle the caller management
// It will use vm.readCallers() to determine the owner
// Keep prank active for all vault creations
⋮----
// Grant required roles to curator for the first vault
⋮----
function _subnetwork() internal view returns (bytes32) {
⋮----
function _labelVault(address vaultAddr, string memory label) internal {
⋮----
function _grantRolesForNetworkRestakeDelegator(address vaultAddr) internal {
⋮----
// The admin is the curator who was the caller when the vault was created
// Roles should already be granted during initialization, but grant them explicitly to be safe
⋮----
function _grantRolesForFullRestakeDelegator(address vaultAddr) internal {
⋮----
function _ensureOperatorOptIn(address vaultAddr) internal {
⋮----
function _setupStakeForNetworkRestake(
⋮----
function _setupStakeForFullRestake(
⋮----
function test_RegisterOperator() public {
⋮----
function test_OptInVault() public {
⋮----
function test_OptInNetwork() public {
⋮----
function test_SetHook() public {
⋮----
function test_SetMaxNetworkLimit() public {
⋮----
function test_SetNetworkLimit() public {
⋮----
function test_SetOperatorNetworkShares() public {
⋮----
function test_SetResolver() public {
⋮----
function test_VetoSlash() public {
````
## File: test/integration/actions/ScriptBaseHarness.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ScriptBase} from "../../../script/utils/ScriptBase.s.sol";
⋮----
abstract contract ScriptBaseHarness is ScriptBase {
⋮----
function sendTransaction(address target, bytes memory data) public virtual override {
````
## File: test/integration/base/SymbioticCoreBindingsBase.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "../../../test/integration/SymbioticCoreImports.sol";
⋮----
import {SymbioticCoreConstants} from "../../../test/integration/SymbioticCoreConstants.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
abstract contract SymbioticCoreBindingsBase is Test {
⋮----
// implement in child contract according to the needs, either use prank or broadcast
modifier broadcast(address who) virtual;
⋮----
function _createVault_SymbioticCore(
⋮----
function _registerOperator_SymbioticCore(SymbioticCoreConstants.Core memory symbioticCore, address who)
⋮----
function _registerNetwork_SymbioticCore(SymbioticCoreConstants.Core memory symbioticCore, address who)
⋮----
function _optInVault_SymbioticCore(SymbioticCoreConstants.Core memory symbioticCore, address who, address vault)
⋮----
function _optInVault_SymbioticCore(
⋮----
function _optInNetwork_SymbioticCore(
⋮----
function _optOutVault_SymbioticCore(SymbioticCoreConstants.Core memory symbioticCore, address who, address vault)
⋮----
function _optOutVault_SymbioticCore(
⋮----
function _optOutNetwork_SymbioticCore(
⋮----
function _setOperatorMetadata_SymbioticCore(
⋮----
function _setNetworkMetadata_SymbioticCore(
⋮----
function _setMiddleware_SymbioticCore(
⋮----
function _deposit_SymbioticCore(address who, address vault, address onBehalfOf, uint256 amount)
⋮----
function _deposit_SymbioticCore(address who, address vault, uint256 amount)
⋮----
function _withdraw_SymbioticCore(address who, address vault, address claimer, uint256 amount)
⋮----
function _withdraw_SymbioticCore(address who, address vault, uint256 amount)
⋮----
function _redeem_SymbioticCore(address who, address vault, address claimer, uint256 shares)
⋮----
function _redeem_SymbioticCore(address who, address vault, uint256 shares)
⋮----
function _claim_SymbioticCore(address who, address vault, address recipient, uint256 epoch)
⋮----
function _claim_SymbioticCore(address who, address vault, uint256 epoch) internal virtual returns (uint256 amount) {
⋮----
function _claimBatch_SymbioticCore(address who, address vault, address recipient, uint256[] memory epochs)
⋮----
function _claimBatch_SymbioticCore(address who, address vault, uint256[] memory epochs)
⋮----
function _setDepositWhitelist_SymbioticCore(address who, address vault, bool status)
⋮----
function _setDepositorWhitelistStatus_SymbioticCore(address who, address vault, address account, bool status)
⋮----
function _setIsDepositLimit_SymbioticCore(address who, address vault, bool status) internal virtual broadcast(who) {
⋮----
function _setDepositLimit_SymbioticCore(address who, address vault, uint256 limit) internal virtual broadcast(who) {
⋮----
function _setMaxNetworkLimit_SymbioticCore(address who, address vault, uint96 identifier, uint256 amount)
⋮----
function _setHook_SymbioticCore(address who, address vault, address hook) internal virtual broadcast(who) {
⋮----
function _setNetworkLimit_SymbioticCore(address who, address vault, bytes32 subnetwork, uint256 amount)
⋮----
// ISymbioticFullRestakeDelegator(ISymbioticVault(vault).delegator()).setNetworkLimit(subnetwork, amount);
// ISymbioticOperatorSpecificDelegator(ISymbioticVault(vault).delegator()).setNetworkLimit(subnetwork, amount);
⋮----
function _setOperatorNetworkShares_SymbioticCore(
⋮----
function _setOperatorNetworkLimit_SymbioticCore(
⋮----
function _slash_SymbioticCore(
⋮----
function _requestSlash_SymbioticCore(
⋮----
function _executeSlash_SymbioticCore(address who, address vault, uint256 slashIndex)
⋮----
function _vetoSlash_SymbioticCore(address who, address vault, uint256 slashIndex) internal virtual broadcast(who) {
⋮----
function _setResolver_SymbioticCore(address who, address vault, uint96 identifier, address resolver)
⋮----
function _grantRole_SymbioticCore(address who, address where, bytes32 role, address account)
⋮----
function _grantRoleDefaultAdmin_SymbioticCore(address who, address where, address account) internal virtual {
⋮----
function _grantRoleDepositWhitelistSet_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
function _grantRoleDepositorWhitelist_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
function _grantRoleIsDepositLimitSet_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
function _grantRoleDepositLimitSet_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
function _grantRoleHookSet_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
function _grantRole_NetworkLimitSet_SymbioticCore(address who, address vault, address account) internal virtual {
⋮----
// _grantRole_SymbioticCore(who, vault, ISymbioticFullRestakeDelegator(ISymbioticVault(vault).delegator()).NETWORK_LIMIT_SET_ROLE(), account);
// _grantRole_SymbioticCore(who, vault, ISymbioticOperatorSpecificDelegator(ISymbioticVault(vault).delegator()).NETWORK_LIMIT_SET_ROLE(), account);
⋮----
function _grantRole_OperatorNetworkSharesSet_SymbioticCore(address who, address vault, address account)
⋮----
function _grantRole_OperatorNetworkLimitSet_SymbioticCore(address who, address vault, address account)
````
## File: test/integration/base/SymbioticCoreInitBase.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "../SymbioticCoreImports.sol";
⋮----
import "../SymbioticUtils.sol";
import {SymbioticCoreConstants} from "../SymbioticCoreConstants.sol";
import {SymbioticCoreBytecode} from "../SymbioticCoreBytecode.sol";
import {SymbioticCoreBindingsBase} from "./SymbioticCoreBindingsBase.sol";
⋮----
import {Token} from "../../mocks/Token.sol";
import {FeeOnTransferToken} from "../../mocks/FeeOnTransferToken.sol";
⋮----
import {IERC5267} from "@openzeppelin/contracts/interfaces/IERC5267.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
abstract contract SymbioticCoreInitBase is SymbioticUtils, SymbioticCoreBindingsBase {
⋮----
// General config
⋮----
// Vaults-related config
⋮----
// Staker-related config
⋮----
// Delegation-related config
⋮----
// ------------------------------------------------------------ GENERAL HELPERS ------------------------------------------------------------ //
⋮----
function _initCore_SymbioticCore() internal virtual {
⋮----
// if useExisting is true, the core is not deployed, but the addresses are returned
function _initCore_SymbioticCore(bool useExisting) internal virtual returns (SymbioticCoreConstants.Core memory) {
⋮----
// return existing core
⋮----
function _deployCreate2(bytes32 salt, bytes memory baseCode, bytes memory constructorArgs)
⋮----
// Copy `baseCode` one word at a time, backwards.
⋮----
o := add(o, w) // `sub(o, 0x20)`.
⋮----
// Copy `constructorArgs` one word at a time, backwards.
⋮----
mstore(last, 0) // Zeroize the slot after the bytes.
mstore(creationCode, totalLen) // Store the length.
mstore(0x40, add(last, 0x20)) // Allocate memory.
⋮----
function _deployCoreFactories(address deployer) internal virtual {
⋮----
function _deployCoreRegistries() internal virtual {
⋮----
function _deployCoreServices() internal virtual {
⋮----
function _whitelistVaultImplementations() internal virtual {
⋮----
function _whitelistDelegatorImplementations() internal virtual {
⋮----
function _whitelistSlasherImplementations() internal virtual {
⋮----
// ------------------------------------------------------------ TOKEN-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getToken_SymbioticCore() internal virtual returns (address) {
⋮----
function _getFeeOnTransferToken_SymbioticCore() internal virtual returns (address) {
⋮----
function _getSupportedTokens_SymbioticCore() internal virtual returns (address[] memory supportedTokens) {
⋮----
// ------------------------------------------------------------ VAULT-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getVault_SymbioticCore(address collateral) internal virtual returns (address) {
⋮----
function _getVault_SymbioticCore(VaultParams memory params) internal virtual returns (address vault) {
⋮----
function _getVaultRandom_SymbioticCore(address[] memory operators, address collateral)
⋮----
function _vaultValidating_SymbioticCore(address vault, bytes32 subnetwork) internal virtual returns (bool) {
⋮----
// ------------------------------------------------------------ OPERATOR-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getOperator_SymbioticCore() internal virtual returns (Vm.Wallet memory) {
⋮----
function _getOperatorWithOptIns_SymbioticCore(address vault) internal virtual returns (Vm.Wallet memory) {
⋮----
function _getOperatorWithOptIns_SymbioticCore(address[] memory vaults) internal virtual returns (Vm.Wallet memory) {
⋮----
function _getOperatorWithOptIns_SymbioticCore(address vault, address network)
⋮----
function _getOperatorWithOptIns_SymbioticCore(address[] memory vaults, address[] memory networks)
⋮----
function _operatorRegister_SymbioticCore(address operator) internal virtual {
⋮----
function _operatorOptIn_SymbioticCore(address operator, address where) internal virtual {
⋮----
function _operatorOptInWeak_SymbioticCore(address operator, address where) internal virtual {
⋮----
function _operatorOptOut_SymbioticCore(address operator, address where) internal virtual {
⋮----
function _operatorOptInSignature_SymbioticCore(Vm.Wallet memory operator, address where)
⋮----
function _operatorOptOutSignature_SymbioticCore(Vm.Wallet memory operator, address where)
⋮----
function computeOptInDigest_SymbioticCore(
⋮----
function computeOptOutDigest_SymbioticCore(
⋮----
function _computeDomainSeparator_SymbioticCore(address service) internal view virtual returns (bytes32) {
⋮----
function _operatorPossibleValidating_SymbioticCore(address operator, address vault, bytes32 subnetwork)
⋮----
function _operatorConfirmedValidating_SymbioticCore(address operator, address vault, bytes32 subnetwork)
⋮----
// ------------------------------------------------------------ NETWORK-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getNetwork_SymbioticCore() internal virtual returns (Vm.Wallet memory) {
⋮----
function _getNetworkWithMiddleware_SymbioticCore(address middleware) internal virtual returns (Vm.Wallet memory) {
⋮----
function _getNetworkWithMaxNetworkLimits_SymbioticCore(uint96 identifier, address vault, uint256 maxNetworkLimit)
⋮----
function _getNetworkWithMiddlewareWithMaxNetworkLimits_SymbioticCore(
⋮----
function _getNetworkWithMaxNetworkLimitsRandom_SymbioticCore(uint96 identifier, address vault)
⋮----
function _getNetworkWithMiddlewareWithMaxNetworkLimitsRandom_SymbioticCore(
⋮----
function _getNetworkWithMaxNetworkLimits_SymbioticCore(
⋮----
function _getNetworkWithMaxNetworkLimitsRandom_SymbioticCore(uint96[] memory identifiers, address[] memory vaults)
⋮----
function _getNetworkWithMaxNetworkLimitsWithResolvers_SymbioticCore(
⋮----
function _getNetworkWithMiddlewareWithMaxNetworkLimitsWithResolvers_SymbioticCore(
⋮----
function _getNetworkWithMaxNetworkLimitsWithResolversRandom_SymbioticCore(
⋮----
function _getNetworkWithMiddlewareWithMaxNetworkLimitsWithResolversRandom_SymbioticCore(
⋮----
function _networkRegister_SymbioticCore(address network) internal virtual {
⋮----
function _networkSetMiddleware_SymbioticCore(address network, address middleware) internal virtual {
⋮----
function _networkSetMaxNetworkLimit_SymbioticCore(
⋮----
function _networkSetMaxNetworkLimitRandom_SymbioticCore(address network, address vault, uint96 identifier)
⋮----
function _networkSetMaxNetworkLimitReset_SymbioticCore(address network, address vault, uint96 identifier)
⋮----
function _networkSetResolver_SymbioticCore(address network, address vault, uint96 identifier, address resolver)
⋮----
function _networkPossibleUtilizing_SymbioticCore(
⋮----
// ------------------------------------------------------------ STAKER-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getStaker_SymbioticCore(address[] memory possibleTokens) internal virtual returns (Vm.Wallet memory);
⋮----
function _getStakerWithStake_SymbioticCore(address[] memory possibleTokens, address vault)
⋮----
function _getStakerWithStake_SymbioticCore(address[] memory possibleTokens, address[] memory vaults)
⋮----
function _stakerDeposit_SymbioticCore(address staker, address vault, uint256 amount) internal virtual {
⋮----
function _stakerDepositRandom_SymbioticCore(address staker, address vault) internal virtual {
⋮----
function _stakerWithdraw_SymbioticCore(address staker, address vault, uint256 amount) internal virtual {
⋮----
function _stakerWithdrawRandom_SymbioticCore(address staker, address vault) internal virtual {
⋮----
function _stakerRedeem_SymbioticCore(address staker, address vault, uint256 shares) internal virtual {
⋮----
function _stakerClaim_SymbioticCore(address staker, address vault, uint256 epoch) internal virtual {
⋮----
function _stakerClaimBatch_SymbioticCore(address staker, address vault, uint256[] memory epochs) internal virtual {
⋮----
// ------------------------------------------------------------ CURATOR-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _curatorSetHook_SymbioticCore(address curator, address vault, address hook) internal virtual {
⋮----
function _curatorSetNetworkLimit_SymbioticCore(address curator, address vault, bytes32 subnetwork, uint256 amount)
⋮----
function _curatorSetNetworkLimitRandom_SymbioticCore(address curator, address vault, bytes32 subnetwork)
⋮----
function _curatorSetNetworkLimitReset_SymbioticCore(address curator, address vault, bytes32 subnetwork)
⋮----
function _curatorSetOperatorNetworkShares_SymbioticCore(
⋮----
function _curatorSetOperatorNetworkSharesRandom_SymbioticCore(
⋮----
function _curatorSetOperatorNetworkSharesReset_SymbioticCore(
⋮----
function _curatorSetOperatorNetworkLimit_SymbioticCore(
⋮----
function _curatorSetOperatorNetworkLimitRandom_SymbioticCore(
⋮----
function _curatorSetOperatorNetworkLimitReset_SymbioticCore(
⋮----
function _curatorDelegateNetworkRandom_SymbioticCore(address curator, address vault, bytes32 subnetwork)
⋮----
function _curatorDelegateNetworkHasRoles_SymbioticCore(
⋮----
bytes32 /* subnetwork */
⋮----
function _curatorDelegateOperatorRandom_SymbioticCore(
⋮----
function _curatorDelegateOperatorHasRoles_SymbioticCore(
⋮----
bytes32, /* subnetwork */
⋮----
function _curatorDelegateRandom_SymbioticCore(address curator, address vault, bytes32 subnetwork, address operator)
⋮----
function _curatorDelegateHasRoles_SymbioticCore(
⋮----
function _curatorDelegateToNetworkInternal_SymbioticCore(address curator, address vault, bytes32 subnetwork)
⋮----
function _curatorDelegateToOperatorInternal_SymbioticCore(
⋮----
function _curatorSetDepositWhitelist_SymbioticCore(address curator, address vault, bool status) internal virtual {
⋮----
function _curatorSetDepositorWhitelistStatus_SymbioticCore(
⋮----
function _curatorSetIsDepositLimit_SymbioticCore(address curator, address vault, bool status) internal virtual {
⋮----
function _curatorSetDepositLimit_SymbioticCore(address curator, address vault, uint256 limit) internal virtual {
⋮----
function _stopBroadcastWhenCallerModeIsSingle(Vm.CallerMode callerMode) internal virtual;
⋮----
function _startBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode, address deployer) internal virtual;
⋮----
function _stopBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode) internal virtual;
⋮----
function _startBroadcastWhenCallerModeIsRecurrent(Vm.CallerMode callerMode, address deployer) internal virtual;
⋮----
function _stopBroadcastWhenCallerModeIsSingleOrRecurrent(Vm.CallerMode callerMode) internal virtual;
````
## File: test/integration/SymbioticCoreBindings.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SymbioticCoreBindingsBase} from "./base/SymbioticCoreBindingsBase.sol";
⋮----
contract SymbioticCoreBindings is SymbioticCoreBindingsBase {
modifier broadcast(address who) virtual override {
````
## File: test/integration/SymbioticCoreBytecode.sol
````
// SPDX-License-Identifier: MIT
⋮----
function vaultFactory() internal pure returns (bytes memory) {
⋮----
function delegatorFactory() internal pure returns (bytes memory) {
⋮----
function slasherFactory() internal pure returns (bytes memory) {
⋮----
function networkRegistry() internal pure returns (bytes memory) {
⋮----
function operatorRegistry() internal pure returns (bytes memory) {
⋮----
function metadataService() internal pure returns (bytes memory) {
⋮----
function networkMiddlewareService() internal pure returns (bytes memory) {
⋮----
function optInService() internal pure returns (bytes memory) {
⋮----
function vaultConfigurator() internal pure returns (bytes memory) {
⋮----
function vault() internal pure returns (bytes memory) {
⋮----
function vaultTokenized() internal pure returns (bytes memory) {
⋮----
function networkRestakeDelegator() internal pure returns (bytes memory) {
⋮----
function fullRestakeDelegator() internal pure returns (bytes memory) {
⋮----
function operatorSpecificDelegator() internal pure returns (bytes memory) {
⋮----
function operatorNetworkSpecificDelegator() internal pure returns (bytes memory) {
⋮----
function slasher() internal pure returns (bytes memory) {
⋮----
function vetoSlasher() internal pure returns (bytes memory) {
````
## File: test/integration/SymbioticCoreConstants.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticCoreImports.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
function coreSupported() internal view returns (bool) {
⋮----
function core() internal view returns (Core memory) {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
⋮----
// hoodi
⋮----
function token(string memory symbol) internal view returns (address) {
⋮----
function tokenSupported(string memory symbol) internal view returns (bool) {
⋮----
function wstETH() internal view returns (address) {
⋮----
function cbETH() internal view returns (address) {
⋮----
function wBETH() internal view returns (address) {
⋮----
function rETH() internal view returns (address) {
⋮----
function mETH() internal view returns (address) {
⋮----
function swETH() internal view returns (address) {
⋮----
function sfrxETH() internal view returns (address) {
⋮----
function ETHx() internal view returns (address) {
⋮----
function ENA() internal view returns (address) {
⋮----
function sUSDe() internal view returns (address) {
⋮----
function WBTC() internal view returns (address) {
⋮----
function tBTC() internal view returns (address) {
⋮----
function LsETH() internal view returns (address) {
⋮----
function osETH() internal view returns (address) {
⋮----
function ETHFI() internal view returns (address) {
⋮----
function FXS() internal view returns (address) {
⋮----
function LBTC() internal view returns (address) {
⋮----
function SWELL() internal view returns (address) {
⋮----
function MANTA() internal view returns (address) {
⋮----
function wstETHSupported() internal view returns (bool) {
⋮----
function cbETHSupported() internal view returns (bool) {
⋮----
function wBETHSupported() internal view returns (bool) {
⋮----
function rETHSupported() internal view returns (bool) {
⋮----
function mETHSupported() internal view returns (bool) {
⋮----
function swETHSupported() internal view returns (bool) {
⋮----
function sfrxETHSupported() internal view returns (bool) {
⋮----
function ETHxSupported() internal view returns (bool) {
⋮----
function ENASupported() internal view returns (bool) {
⋮----
function sUSDeSupported() internal view returns (bool) {
⋮----
function WBTCSupported() internal view returns (bool) {
⋮----
function tBTCSupported() internal view returns (bool) {
⋮----
function LsETHSupported() internal view returns (bool) {
⋮----
function osETHSupported() internal view returns (bool) {
⋮----
function ETHFISupported() internal view returns (bool) {
⋮----
function FXSSupported() internal view returns (bool) {
⋮----
function LBTCSupported() internal view returns (bool) {
⋮----
function SWELLSupported() internal view returns (bool) {
⋮----
function MANTASupported() internal view returns (bool) {
⋮----
function allTokens() internal view returns (string[] memory result) {
⋮----
function supportedTokens() internal view returns (string[] memory result) {
````
## File: test/integration/SymbioticCoreImports.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry as ISymbioticRegistry} from "../../src/interfaces/common/IRegistry.sol";
import {IEntity as ISymbioticEntity} from "../../src/interfaces/common/IEntity.sol";
import {IFactory as ISymbioticFactory} from "../../src/interfaces/common/IFactory.sol";
import {IMigratableEntity as ISymbioticMigratableEntity} from "../../src/interfaces/common/IMigratableEntity.sol";
import {IMigratablesFactory as ISymbioticMigratablesFactory} from "../../src/interfaces/common/IMigratablesFactory.sol";
import {
IStaticDelegateCallable as ISymbioticStaticDelegateCallable
} from "../../src/interfaces/common/IStaticDelegateCallable.sol";
import {IVault as ISymbioticVault} from "../../src/interfaces/vault/IVault.sol";
import {IVaultTokenized as ISymbioticVaultTokenized} from "../../src/interfaces/vault/IVaultTokenized.sol";
import {IVaultFactory as ISymbioticVaultFactory} from "../../src/interfaces/IVaultFactory.sol";
import {IBaseDelegator as ISymbioticBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {
INetworkRestakeDelegator as ISymbioticNetworkRestakeDelegator
} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {
IFullRestakeDelegator as ISymbioticFullRestakeDelegator
} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {
IOperatorSpecificDelegator as ISymbioticOperatorSpecificDelegator
} from "../../src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {
IOperatorNetworkSpecificDelegator as ISymbioticOperatorNetworkSpecificDelegator
} from "../../src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IDelegatorFactory as ISymbioticDelegatorFactory} from "../../src/interfaces/IDelegatorFactory.sol";
import {IBaseSlasher as ISymbioticBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher as ISymbioticSlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher as ISymbioticVetoSlasher} from "../../src/interfaces/slasher/IVetoSlasher.sol";
import {ISlasherFactory as ISymbioticSlasherFactory} from "../../src/interfaces/ISlasherFactory.sol";
import {INetworkRegistry as ISymbioticNetworkRegistry} from "../../src/interfaces/INetworkRegistry.sol";
import {IOperatorRegistry as ISymbioticOperatorRegistry} from "../../src/interfaces/IOperatorRegistry.sol";
import {IMetadataService as ISymbioticMetadataService} from "../../src/interfaces/service/IMetadataService.sol";
import {
INetworkMiddlewareService as ISymbioticNetworkMiddlewareService
} from "../../src/interfaces/service/INetworkMiddlewareService.sol";
import {IOptInService as ISymbioticOptInService} from "../../src/interfaces/service/IOptInService.sol";
import {IVaultConfigurator as ISymbioticVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {Checkpoints as SymbioticCheckpoints} from "../../src/contracts/libraries/Checkpoints.sol";
import {ERC4626Math as SymbioticERC4626Math} from "../../src/contracts/libraries/ERC4626Math.sol";
import {Subnetwork as SymbioticSubnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
interface SymbioticCoreImports {}
````
## File: test/integration/SymbioticCoreImportsContracts.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Registry as SymbioticRegistry} from "../../src/contracts/common/Registry.sol";
import {Entity as SymbioticEntity} from "../../src/contracts/common/Entity.sol";
import {Factory as SymbioticFactory} from "../../src/contracts/common/Factory.sol";
import {MigratableEntity as SymbioticMigratableEntity} from "../../src/contracts/common/MigratableEntity.sol";
import {MigratablesFactory as SymbioticMigratablesFactory} from "../../src/contracts/common/MigratablesFactory.sol";
import {
StaticDelegateCallable as SymbioticStaticDelegateCallable
} from "../../src/contracts/common/StaticDelegateCallable.sol";
import {Vault as SymbioticVault} from "../../src/contracts/vault/Vault.sol";
import {VaultTokenized as SymbioticVaultTokenized} from "../../src/contracts/vault/VaultTokenized.sol";
import {VaultFactory as SymbioticVaultFactory} from "../../src/contracts/VaultFactory.sol";
import {BaseDelegator as SymbioticBaseDelegator} from "../../src/contracts/delegator/BaseDelegator.sol";
import {
NetworkRestakeDelegator as SymbioticNetworkRestakeDelegator
} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {
FullRestakeDelegator as SymbioticFullRestakeDelegator
} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {
OperatorSpecificDelegator as SymbioticOperatorSpecificDelegator
} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {
OperatorNetworkSpecificDelegator as SymbioticOperatorNetworkSpecificDelegator
} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {DelegatorFactory as SymbioticDelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {BaseSlasher as SymbioticBaseSlasher} from "../../src/contracts/slasher/BaseSlasher.sol";
import {Slasher as SymbioticSlasher, ISlasher as ISymbioticSlasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher as SymbioticVetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
import {SlasherFactory as SymbioticSlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry as SymbioticNetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {
OperatorRegistry as SymbioticOperatorRegistry,
IOperatorRegistry as ISymbioticOperatorRegistry
} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService as SymbioticMetadataService} from "../../src/contracts/service/MetadataService.sol";
import {
NetworkMiddlewareService as SymbioticNetworkMiddlewareService
} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService as SymbioticOptInService} from "../../src/contracts/service/OptInService.sol";
import {VaultConfigurator as SymbioticVaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
⋮----
interface SymbioticCoreImportsContracts {}
````
## File: test/integration/SymbioticCoreInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticCoreImports.sol";
⋮----
import "./SymbioticInit.sol";
import {SymbioticCoreConstants} from "./SymbioticCoreConstants.sol";
import {SymbioticCoreInitBase} from "./base/SymbioticCoreInitBase.sol";
import {SymbioticCoreBindings} from "./SymbioticCoreBindings.sol";
import {Token} from "../mocks/Token.sol";
import {FeeOnTransferToken} from "../mocks/FeeOnTransferToken.sol";
⋮----
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";
⋮----
contract SymbioticCoreInit is SymbioticCoreInitBase, SymbioticInit, SymbioticCoreBindings {
function setUp() public virtual override {
⋮----
function _getStaker_SymbioticCore(address[] memory possibleTokens)
⋮----
); // should cover most cases
⋮----
// ------------------------------------------------------------ BROADCAST HELPERS ------------------------------------------------------------ //
⋮----
function _stopBroadcastWhenCallerModeIsSingle(Vm.CallerMode callerMode) internal virtual override {
⋮----
function _startBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode, address deployer)
⋮----
function _stopBroadcastWhenCallerModeIsNotRecurrent(Vm.CallerMode callerMode) internal virtual override {
⋮----
function _startBroadcastWhenCallerModeIsRecurrent(Vm.CallerMode callerMode, address deployer)
⋮----
function _stopBroadcastWhenCallerModeIsSingleOrRecurrent(Vm.CallerMode callerMode) internal virtual override {
````
## File: test/integration/SymbioticCoreIntegration.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticCoreInit.sol";
⋮----
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
⋮----
contract SymbioticCoreIntegration is SymbioticCoreInit {
⋮----
// allocated network stake
⋮----
// fully opted in and has stake
⋮----
// only needs to opt into network (may be used to test opt-in with signature)
⋮----
uint256 public SYMBIOTIC_CORE_DEPOSIT_INTO_VAULT_CHANCE = 1; // lower -> higher probability
⋮----
function setUp() public virtual override {
⋮----
function _loadExistingEntities_SymbioticCore() internal virtual {
⋮----
function _loadExistingVaultsAndTokens_SymbioticCore() internal virtual {
⋮----
function _loadExistingNetworks_SymbioticCore() internal virtual {
⋮----
function _loadExistingOperators_SymbioticCore() internal virtual {
⋮----
function _addPossibleTokens_SymbioticCore() internal virtual {
⋮----
function _addExistingEntities_SymbioticCore() internal virtual {
⋮----
function _addExistingTokens_SymbioticCore() internal virtual {
⋮----
function _addExistingVaults_SymbioticCore() internal virtual {
⋮----
function _addExistingNetworks_SymbioticCore() internal virtual {
⋮----
function _addExistingOperators_SymbioticCore() internal virtual {
⋮----
function _createEnvironment_SymbioticCore() internal virtual {
⋮----
function _createParties_SymbioticCore(
⋮----
function _createNetworks_SymbioticCore(uint256 numberOfNetworks) internal virtual {
⋮----
function _createOperators_SymbioticCore(uint256 numberOfOperators) internal virtual {
⋮----
function _createVaults_SymbioticCore(uint256 numberOfVaults) internal virtual {
⋮----
function _createStakers_SymbioticCore(uint256 numberOfStakers) internal virtual {
⋮----
function _depositIntoVaults_SymbioticCore() internal virtual {
⋮----
function _withdrawFromVaults_SymbioticCore() internal virtual {
⋮----
function _setMaxNetworkLimits_SymbioticCore() internal virtual {
⋮----
function _delegateToNetworks_SymbioticCore() internal virtual {
⋮----
function _delegateToNetworkTry_SymbioticCore(address vault, bytes32 subnetwork)
⋮----
function _delegateToOperators_SymbioticCore() internal virtual {
⋮----
function _delegateToOperatorTry_SymbioticCore(address vault, bytes32 subnetwork, address operator)
⋮----
function _delegateTry_SymbioticCore(address vault, bytes32 subnetwork, address operator)
⋮----
function _optInOperators_SymbioticCore() internal virtual {
⋮----
function _optInOperatorsVaults_SymbioticCore() internal virtual {
⋮----
function _optInOperatorsNetworks_SymbioticCore() internal virtual {
⋮----
function _addDataForNetworks_SymbioticCore() internal virtual {
````
## File: test/integration/SymbioticCoreIntegrationExample.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticCoreIntegration.sol";
⋮----
import {console2} from "forge-std/Test.sol";
⋮----
contract SymbioticCoreIntegrationExample is SymbioticCoreIntegration {
⋮----
uint256 public SELECT_OPERATOR_CHANCE = 1; // lower -> higher probability
⋮----
function setUp() public override {
// vm.selectFork(vm.createFork(vm.rpcUrl("holesky")));
// SYMBIOTIC_INIT_BLOCK = 2_727_202;
// SYMBIOTIC_CORE_USE_EXISTING_DEPLOYMENT = true;
⋮----
function test_Network() public {
⋮----
function test_NetworkAdvanced() public {
⋮----
function test_Simple() public {
````
## File: test/integration/SymbioticInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SymbioticUtils} from "./SymbioticUtils.sol";
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {Test} from "forge-std/Test.sol";
import {Vm, VmSafe} from "forge-std/Vm.sol";
⋮----
contract SymbioticInit is SymbioticUtils, Test {
⋮----
// General config
⋮----
function setUp() public virtual {
⋮----
function _skipBlocks_Symbiotic(uint256 number) internal virtual {
⋮----
function _deal_Symbiotic(address token, address to, uint256 give, bool adjust) public virtual {
⋮----
function _supportsDeal_Symbiotic(address token) internal virtual returns (bool) {
````
## File: test/integration/SymbioticUtils.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {StdUtils} from "forge-std/StdUtils.sol";
import {Vm, VmSafe} from "forge-std/Vm.sol";
⋮----
contract SymbioticUtils is StdUtils {
⋮----
// ------------------------------------------------------------ GENERAL HELPERS ------------------------------------------------------------ //
⋮----
function _random_Symbiotic() internal virtual returns (uint256) {
⋮----
function _randomWithBounds_Symbiotic(uint256 lower, uint256 upper) internal virtual returns (uint256) {
⋮----
function _randomChoice_Symbiotic(uint256 coef) internal virtual returns (bool) {
⋮----
function _randomPick_Symbiotic(address[] memory array) internal virtual returns (address) {
⋮----
function _randomPick_Symbiotic(uint256[] memory array) internal virtual returns (uint256) {
⋮----
function _randomPick_Symbiotic(uint64[] memory array) internal virtual returns (uint64) {
⋮----
function _getAccount_Symbiotic() internal virtual returns (Vm.Wallet memory) {
⋮----
function _contains_Symbiotic(address[] memory array, address element) internal virtual returns (bool) {
⋮----
function _contains_Symbiotic(Vm.Wallet[] memory array, Vm.Wallet memory element) internal virtual returns (bool) {
⋮----
function _createWalletByAddress_Symbiotic(address addr) internal virtual returns (Vm.Wallet memory) {
⋮----
function _getWalletByAddress_Symbiotic(Vm.Wallet[] memory array, address element)
⋮----
function _vmWalletToAddress_Symbiotic(Vm.Wallet memory wallet) internal pure virtual returns (address) {
⋮----
function _vmWalletsToAddresses_Symbiotic(Vm.Wallet[] memory wallets)
⋮----
function _normalizeForToken_Symbiotic(uint256 amount, address token) internal virtual returns (uint256) {
⋮----
modifier equalLengthsAddressAddress_Symbiotic(address[] memory a, address[] memory b) {
⋮----
modifier equalLengthsUint96Address_Symbiotic(uint96[] memory a, address[] memory b) {
⋮----
modifier equalLengthsUint96Uint256_SymbioticCore(uint96[] memory a, uint256[] memory b) {
````
## File: test/libraries/Checkpoints.t.sol
````
// SPDX-License-Identifier: MIT
// This file was procedurally generated from scripts/generate/templates/Checkpoints.t.js.
⋮----
import {Test} from "forge-std/Test.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Checkpoints} from "../../src/contracts/libraries/Checkpoints.sol";
⋮----
contract CheckpointsTrace208Test is Test {
⋮----
// Maximum gap between keys used during the fuzzing tests: the `_prepareKeys` function with make sure that
// key#n+1 is in the [key#n, key#n + _KEY_MAX_GAP] range.
⋮----
// helpers
function _boundUint48(uint48 x, uint48 min, uint48 max) internal pure returns (uint48) {
⋮----
function _prepareKeys(uint48[] memory keys, uint48 maxSpread) internal pure {
⋮----
function _prepareKeysUnrepeated(uint48[] memory keys, uint48 maxSpread) internal pure {
⋮----
function _assertLatestCheckpoint(bool exist, uint48 key, uint208 value) internal {
⋮----
// tests
function testPush(uint48[] memory keys, uint208[] memory values, uint48 pastKey) public {
⋮----
// initial state
⋮----
// push
⋮----
// check length & latest
⋮----
// used to test reverts
function push(uint48 key, uint208 value) external {
⋮----
function testLookup(uint48[] memory keys, uint208[] memory values, uint48 lookup) public {
⋮----
// track expected result of lookups
⋮----
// find the first key that is not smaller than the lookup key
⋮----
function testUpperLookupRecentWithHint(
⋮----
// Build checkpoints
⋮----
// Test upperLookupRecentCheckpoint without hint
function testUpperLookupRecentCheckpoint(uint48[] memory keys, uint208[] memory values, uint48 lookup) public {
⋮----
// Expected values
⋮----
// Test function
⋮----
// Test upperLookupRecentCheckpoint with hint
function testUpperLookupRecentCheckpointWithHint(
⋮----
// Test latest
function testLatest(uint48[] memory keys, uint208[] memory values) public {
⋮----
// Test latestCheckpoint
function testLatestCheckpoint(uint48[] memory keys, uint208[] memory values) public {
⋮----
// Test length
function testLength(uint48[] memory keys, uint208[] memory values) public {
⋮----
// Test at
function testAt(uint48[] memory keys, uint208[] memory values, uint32 index) public {
⋮----
// Test pop
function testPop(uint48[] memory keys, uint208[] memory values) public {
⋮----
contract CheckpointsTrace256Test is Test {
⋮----
function _assertLatestCheckpoint(bool exist, uint48 key, uint256 value) internal {
⋮----
function testPush(uint48[] memory keys, uint256[] memory values, uint48 pastKey) public {
⋮----
function push(uint48 key, uint256 value) external {
⋮----
function testLookup(uint48[] memory keys, uint256[] memory values, uint48 lookup) public {
⋮----
function testUpperLookupRecentCheckpoint(uint48[] memory keys, uint256[] memory values, uint48 lookup) public {
⋮----
function testLatest(uint48[] memory keys, uint256[] memory values) public {
⋮----
function testLatestCheckpoint(uint48[] memory keys, uint256[] memory values) public {
⋮----
function testLength(uint48[] memory keys, uint256[] memory values) public {
⋮----
function testAt(uint48[] memory keys, uint256[] memory values, uint32 index) public {
⋮----
function testPop(uint48[] memory keys, uint256[] memory values) public {
````
## File: test/mocks/DAILikeToken.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
⋮----
contract DAILikeToken is ERC20 {
⋮----
// bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
⋮----
// --- Approve by signature ---
function permit(
````
## File: test/mocks/FakeEntity.sol
````
// SPDX-License-Identifier: MIT
⋮----
contract FakeEntity {
⋮----
function setType(uint64 type_) external returns (uint64) {
⋮----
function setA(uint256 _a) public {
````
## File: test/mocks/FeeOnTransferToken.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
⋮----
contract FeeOnTransferToken is ERC20 {
⋮----
function _update(address from, address to, uint256 value) internal override {
````
## File: test/mocks/PermitToken.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
⋮----
contract PermitToken is ERC20, ERC20Permit {
````
## File: test/mocks/RebaseToken.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract RebaseToken is ERC20 {
⋮----
function setMultiplier(uint256 multiplier_) external {
⋮----
function sharesOf(address user) public view returns (uint256) {
⋮----
function balanceOf(address user) public view override returns (uint256) {
⋮----
function transfer(address receiver, uint256 amount) public override returns (bool) {
⋮----
function transferFrom(address sender, address receiver, uint256 amount) public override returns (bool) {
⋮----
function approve(address spender, uint256 amount) public override returns (bool) {
````
## File: test/mocks/SimpleBurner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBurner} from "../../src/interfaces/slasher/IBurner.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract SimpleBurner is IBurner {
⋮----
function onSlash(bytes32 subnetwork, address operator, uint256, uint48) external {
⋮----
function distribute() external {
````
## File: test/mocks/SimpleEntity.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Entity} from "../../src/contracts/common/Entity.sol";
⋮----
contract SimpleEntity is Entity {
⋮----
function setA(uint256 _a) public {
````
## File: test/mocks/SimpleFullRestakeDelegatorHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IDelegatorHook} from "../../src/interfaces/delegator/IDelegatorHook.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "../../src/interfaces/slasher/IVetoSlasher.sol";
⋮----
contract SimpleFullRestakeDelegatorHook is IDelegatorHook {
⋮----
function setData(uint64 slasherType_, uint256 slashableStake_, uint256 stakeAt_, uint256 slashIndex_) external {
⋮----
function onSlash(bytes32 subnetwork, address operator, uint256, uint48, bytes calldata data) external {
````
## File: test/mocks/SimpleMigratableEntity.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {MigratableEntity} from "../../src/contracts/common/MigratableEntity.sol";
⋮----
contract SimpleMigratableEntity is MigratableEntity {
⋮----
function setA(uint256 _a) public {
⋮----
function _migrate(
⋮----
/* oldVersion */
⋮----
/* newVersion */
bytes calldata /* data */
````
## File: test/mocks/SimpleMigratableEntityV2.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {MigratableEntity} from "../../src/contracts/common/MigratableEntity.sol";
⋮----
contract SimpleMigratableEntityV2 is MigratableEntity {
⋮----
function setA(uint256 a_) public {
⋮----
function setB(uint256 b_) public {
⋮----
function _migrate(uint64 oldVersion, uint64 newVersion, bytes calldata data) internal override {
````
## File: test/mocks/SimpleNetworkRestakeDelegatorHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IDelegatorHook} from "../../src/interfaces/delegator/IDelegatorHook.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "../../src/interfaces/slasher/IVetoSlasher.sol";
⋮----
contract SimpleNetworkRestakeDelegatorHook is IDelegatorHook {
⋮----
function setData(uint64 slasherType_, uint256 slashableStake_, uint256 stakeAt_, uint256 slashIndex_) external {
⋮----
function onSlash(bytes32 subnetwork, address operator, uint256, uint48, bytes calldata data) external {
````
## File: test/mocks/SimpleOperatorNetworkSpecificDelegatorHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOperatorNetworkSpecificDelegator} from "../../src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {IDelegatorHook} from "../../src/interfaces/delegator/IDelegatorHook.sol";
⋮----
contract SimpleOperatorNetworkSpecificDelegatorHook is IDelegatorHook {
⋮----
function onSlash(bytes32 subnetwork, address, uint256, uint48, bytes calldata) external {
````
## File: test/mocks/SimpleOperatorSpecificDelegatorHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOperatorSpecificDelegator} from "../../src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IDelegatorHook} from "../../src/interfaces/delegator/IDelegatorHook.sol";
⋮----
contract SimpleOperatorSpecificDelegatorHook is IDelegatorHook {
⋮----
function onSlash(bytes32 subnetwork, address, uint256, uint48, bytes calldata) external {
````
## File: test/mocks/SimpleRegistry.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Registry} from "../../src/contracts/common/Registry.sol";
⋮----
contract SimpleRegistry is Registry {
function register() external returns (address) {
````
## File: test/mocks/Token.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
⋮----
contract Token is ERC20 {
````
## File: test/service/MetadataService.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
⋮----
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {IMetadataService} from "../../src/interfaces/service/IMetadataService.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
contract MetadataServiceTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(string calldata metadataURL_) public {
⋮----
function test_SetMetadataURLRevertNotEntity(string calldata metadataURL_) public {
⋮----
function test_SetMetadataURLRevertAlreadySet(string calldata metadataURL_) public {
````
## File: test/service/NetworkMiddlewareService.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
⋮----
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {INetworkMiddlewareService} from "../../src/interfaces/service/INetworkMiddlewareService.sol";
⋮----
contract MiddlewareServiceTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(address middleware) public {
⋮----
function test_SetMiddlewareRevertNotNetwork(address middleware) public {
⋮----
function test_SetMiddlewareRevertAlreadySet(address middleware) public {
````
## File: test/service/OptInService.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
⋮----
import {OptInService} from "../../src/contracts/service/OptInService.sol";
import {IOptInService} from "../../src/interfaces/service/IOptInService.sol";
⋮----
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
⋮----
import {IERC5267} from "@openzeppelin/contracts/interfaces/IERC5267.sol";
⋮----
contract OperatorOptInServiceTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_OptInRevertNotEntity() public {
⋮----
function test_OptInRevertNotWhereEntity() public {
⋮----
function test_OptInRevertAlreadyOptedIn() public {
⋮----
function test_OptOutRevertNotOptedIn() public {
⋮----
// function test_OptInWithHint(uint48 epochDuration, uint256 num, HintStruct memory hintStruct) public {
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// service = IOptInService(address(new OptInService(address(operatorRegistry), address(networkRegistry), "OperatorNetworkOptInService")));
⋮----
// address operator = alice;
// address where = bob;
⋮----
// vm.startPrank(operator);
// operatorRegistry.registerOperator();
// vm.stopPrank();
⋮----
// vm.startPrank(where);
// networkRegistry.registerNetwork();
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// vm.startPrank(operator);
// service.optIn(where);
// vm.stopPrank();
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
⋮----
// service.optOut(where);
⋮----
// }
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// OptInServiceHints optInServiceHints = new OptInServiceHints();
// bytes memory hint = optInServiceHints.optInHint(address(service), operator, where, timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// service.isOptedInAt(operator, where, timestamp, "");
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// service.isOptedInAt(operator, where, timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
// }
⋮----
function test_OptInWithSignature() public {
⋮----
function test_OptInWithInvalidSignature() public {
⋮----
function test_OptInWithExpiredDeadline() public {
⋮----
function test_IncreaseNonce() public {
⋮----
function test_OptOutWithSignature() public {
⋮----
function test_OptOutWithInvalidSignature() public {
⋮----
function test_OptOutWithExpiredDeadline() public {
⋮----
function computeOptInDigest(IOptInService _service, address who, address where, uint256 nonce, uint48 deadline)
⋮----
function computeOptOutDigest(IOptInService _service, address who, address where, uint256 nonce, uint48 deadline)
⋮----
function _computeDomainSeparator(address _service) internal view returns (bytes32) {
````
## File: test/slasher/Slasher.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {BaseSlasherHints, SlasherHints} from "../../src/contracts/hints/SlasherHints.sol";
import {BaseDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
import {SimpleBurner} from "../mocks/SimpleBurner.sol";
⋮----
contract SlasherTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration) public {
⋮----
function test_CreateRevertNoBurner(uint48 epochDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration) public {
⋮----
function test_Slash(
⋮----
function test_SlashSubnetworks(
⋮----
// Bound parameters
⋮----
// Setup block timestamp
⋮----
// Setup network and operators
⋮----
// Setup subnetwork 0
⋮----
// Test slashable stake for alice on subnetwork 0
⋮----
// Slash alice on subnetwork 0
⋮----
// Verify cumulative slash for alice on subnetwork 0
⋮----
// Test slashable stake for bob on subnetwork 0
⋮----
// Slash bob on subnetwork 0
⋮----
// Verify cumulative slash for bob on subnetwork 0
⋮----
// Second slash for alice on subnetwork 0
⋮----
// Verify second slash results for alice on subnetwork 0
⋮----
// Setup subnetwork 1
⋮----
// Test slashable stake for alice on subnetwork 1
⋮----
// Slash alice on subnetwork 1
⋮----
// Verify cumulative slash for alice on subnetwork 1
⋮----
// Test slashable stake for bob on subnetwork 1
⋮----
// Slash bob on subnetwork 1
⋮----
// Verify cumulative slash for bob on subnetwork 1
⋮----
// Second slash for alice on subnetwork 1
⋮----
// Verify second slash results for alice on subnetwork 1
⋮----
function test_SlashRevertInsufficientSlash1(
⋮----
function test_SlashRevertNotNetworkMiddleware(
⋮----
function test_SlashRevertInsufficientSlash2(
⋮----
function test_SlashRevertInvalidCaptureTimestamp(
⋮----
function test_SlashWithBurner(
// uint48 epochDuration,
⋮----
// uint256 networkLimit,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// networkLimit = bound(networkLimit, 1, type(uint256).max);
⋮----
function test_SlashWithBurnerDisabled(
⋮----
function test_SlashWithBurnerGas(
⋮----
// Create burner and role holders
⋮----
// Create vault, delegator, and slasher
⋮----
// Setup network and operator
⋮----
// Perform slash
⋮----
// Test insufficient burner gas
⋮----
// Test with total gas
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_CumulativeSlashHint(
// uint48 epochDuration,
// uint256 depositAmount,
// uint256 slashAmount1,
// HintStruct memory hintStruct
// ) public {
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
// slashAmount1 = bound(slashAmount1, 1, 10 * 10 ** 18);
// depositAmount = bound(depositAmount, Math.max(1, hintStruct.num * slashAmount1), 1000 * 10 ** 18);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration);
⋮----
// address network = alice;
// _registerNetwork(network, alice);
// _setMaxNetworkLimit(network, type(uint256).max);
⋮----
// _registerOperator(alice);
⋮----
// _optInOperatorVault(alice);
⋮----
// _optInOperatorNetwork(alice, address(network));
⋮----
// _deposit(alice, depositAmount);
⋮----
// _setNetworkLimit(alice, network, type(uint256).max);
⋮----
// _setOperatorNetworkLimit(alice, network, alice, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// blockTimestamp = blockTimestamp + 1;
// vm.warp(blockTimestamp);
⋮----
// _slash(alice, network, alice, slashAmount1, uint48(blockTimestamp - 1), "");
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// optInServiceHints = new OptInServiceHints();
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
// baseSlasherHints = new BaseSlasherHints(address(baseDelegatorHints), address(optInServiceHints));
// bytes memory hint = baseSlasherHints.cumulativeSlashHint(address(slasher), network, alice, timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// slasher.cumulativeSlashAt(network, alice, timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// slasher.cumulativeSlashAt(network, alice, timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// function test_OptInsHints(uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// bytes memory hints = baseSlasherHints.optInHints(address(slasher), network, alice, timestamp);
⋮----
// baseSlasherHints._optIns(address(slasher), network, alice, timestamp, "");
⋮----
// baseSlasherHints._optIns(address(slasher), network, alice, timestamp, hints);
⋮----
// function test_SlashableStakeHints(
⋮----
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 2 * epochDuration);
⋮----
// vm.startPrank(alice);
// try slasher.slash(network, alice, slashAmount1, uint48(blockTimestamp - 1), "") {} catch {}
// vm.stopPrank();
⋮----
// bytes memory hint = baseSlasherHints.slashableStakeHints(address(slasher), network, alice, timestamp);
⋮----
// slasher.slashableStake(network, alice, timestamp, new bytes(0));
⋮----
// slasher.slashableStake(network, alice, timestamp, hint);
⋮----
// function test_OnSlashHints(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 10 * 10 ** 18);
⋮----
// _deposit(alice, amount1);
// _setNetworkLimit(alice, network, amount1);
// _setOperatorNetworkLimit(alice, network, alice, amount1);
⋮----
//
⋮----
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(new VaultHints()));
⋮----
// baseSlasherHints._onSlash(address(slasher), network, alice, amount1, timestamp, "");
⋮----
// bytes memory hints = baseSlasherHints.onSlashHints(address(slasher), network, alice, amount1, timestamp);
// baseSlasherHints._onSlash(address(slasher), network, alice, amount1, timestamp, hints);
⋮----
// struct InputParams {
// uint256 depositAmount;
// uint256 networkLimit;
// uint256 operatorNetworkLimit;
// uint256 slashAmount;
⋮----
// function test_SlashHints(
// uint256 amount1,
⋮----
// HintStruct memory hintStruct,
// InputParams memory inputParams
⋮----
// inputParams.slashAmount = bound(inputParams.slashAmount, 1, 1 * 10 ** 18);
// inputParams.depositAmount =
// bound(inputParams.depositAmount, Math.max(1, inputParams.slashAmount * hintStruct.num), 1000 * 10 ** 18);
// inputParams.networkLimit = bound(inputParams.networkLimit, inputParams.slashAmount, type(uint256).max);
// inputParams.operatorNetworkLimit =
// bound(inputParams.operatorNetworkLimit, inputParams.slashAmount, type(uint256).max);
⋮----
// SlasherHintsHelper slasherHintsHelper = new SlasherHintsHelper();
⋮----
// address middleware = address(slasherHintsHelper);
// _registerNetwork(network, middleware);
⋮----
// _deposit(alice, inputParams.depositAmount);
// _setNetworkLimit(alice, network, inputParams.networkLimit);
// _setOperatorNetworkLimit(alice, network, alice, inputParams.operatorNetworkLimit);
⋮----
// vm.startPrank(alice);
// try slasher.slash(network, alice, inputParams.slashAmount, uint48(blockTimestamp - 1), "") {} catch {}
// vm.stopPrank();
⋮----
// slasherHints = SlasherHints(baseSlasherHints.SLASHER_HINTS());
⋮----
// try slasherHintsHelper.trySlash(address(slasher), network, alice, inputParams.slashAmount, timestamp, "") {}
// catch (bytes memory data) {
// (bool reverted, uint256 gasSpent) = abi.decode(data, (bool, uint256));
// gasStruct.gasSpent1 = gasSpent;
⋮----
// bytes memory hints =
// slasherHints.slashHints(address(slasher), middleware, network, alice, inputParams.slashAmount, timestamp);
// try slasherHintsHelper.trySlash(address(slasher), network, alice, inputParams.slashAmount, timestamp, hints) {}
⋮----
// gasStruct.gasSpent2 = gasSpent;
⋮----
// function test_SlashHintsCompare(
⋮----
// hintStruct.num = bound(hintStruct.num, 1, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 1, Math.min(hintStruct.num, epochDuration));
⋮----
// uint48 timestamp = uint48(blockTimestamp - hintStruct.secondsAgo);
⋮----
// vm.assume(!reverted);
⋮----
// console2.log(gasStruct.gasSpent1, gasStruct.gasSpent2);
// assertLt(gasStruct.gasSpent1 - gasStruct.gasSpent2, 60_000);
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, FullRestakeDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getSlasher(address vault_) internal returns (Slasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkLimit(address user, address network, address operator, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
contract SlasherHintsHelper is Test {
function trySlash(
````
## File: test/slasher/VetoSlasher.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {IMigratableEntityProxy} from "../../src/interfaces/common/IMigratableEntityProxy.sol";
import {IMigratableEntity} from "../../src/interfaces/common/IMigratableEntity.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {IVetoSlasher} from "../../src/interfaces/slasher/IVetoSlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {BaseSlasherHints, VetoSlasherHints} from "../../src/contracts/hints/SlasherHints.sol";
import {BaseDelegatorHints} from "../../src/contracts/hints/DelegatorHints.sol";
import {OptInServiceHints} from "../../src/contracts/hints/OptInServiceHints.sol";
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract VetoSlasherTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 epochDuration, uint48 vetoDuration) public {
⋮----
function test_CreateRevertNotVault(uint48 epochDuration, uint48 vetoDuration, uint256 resolverSetEpochsDelay)
⋮----
function test_CreateRevertInvalidVetoDuration(
⋮----
function test_CreateRevertInvalidResolverSetEpochsDelay(
⋮----
function test_RequestSlash(
// uint48 epochDuration,
⋮----
// epochDuration = uint48(bound(epochDuration, 1, 10 days));
⋮----
// address network = alice;
⋮----
// bytes32 subnetwork_,
⋮----
// address operator_,
⋮----
// bool completed_
⋮----
// assertEq(subnetwork_, alice.subnetwork(0));
// assertEq(operator_, alice);
⋮----
// assertEq(completed_, false);
⋮----
// completed_
⋮----
// assertEq(operator_, bob);
⋮----
function test_RequestSlashRevertNotNetworkMiddleware(
⋮----
function test_RequestSlashRevertInsufficientSlash(
⋮----
function test_RequestSlashRevertInvalidCaptureTimestamp(
⋮----
function test_SetResolver(uint48 epochDuration, uint48 vetoDuration, address resolver1, address resolver2) public {
⋮----
function test_SetResolverRevertAlreadySet1(uint48 epochDuration, uint48 vetoDuration) public {
⋮----
function test_SetResolverRevertAlreadySet2(uint48 epochDuration, uint48 vetoDuration) public {
⋮----
function test_SetResolverRevertNotNetwork(uint48 epochDuration, uint48 vetoDuration) public {
⋮----
function test_ExecuteSlash1(
⋮----
// uint48 vetoDeadline_,
⋮----
// assertEq(vetoDeadline_, uint48(blockTimestamp + slasher.vetoDuration()));
⋮----
// assertEq(vetoDeadline_, uint48(blockTimestamp - (epochDuration - 1) + vetoDuration));
⋮----
function test_ExecuteSlash2(
⋮----
function test_ExecuteSlashWithoutResolver1(
⋮----
// assertEq(vetoDeadline_, uint48(blockTimestamp + vetoDuration));
⋮----
function test_ExecuteSlashWithoutResolver2(
⋮----
function test_ExecuteSlashRevertNotNetworkMiddleware(
⋮----
function test_ExecuteSlashRevertInsufficientSlash1(
⋮----
function test_ExecuteSlashRevertInsufficientSlash2(
⋮----
function test_ExecuteSlashRevertSlashRequestNotExist(
⋮----
function test_ExecuteSlashRevertVetoPeriodNotEnded(
⋮----
function test_ExecuteSlashRevertSlashPeriodEnded(
⋮----
function test_ExecuteSlashRevertSlashRequestCompleted(
⋮----
function test_VetoSlash(
⋮----
function test_VetoSlashRevertSlashRequestNotExist(
⋮----
function test_VetoSlashRevertVetoPeriodEnded(
⋮----
function test_VetoSlashRevertNoResolver1(
⋮----
function test_VetoSlashRevertNoResolver2(
⋮----
function test_VetoSlashRevertNotResolver(
⋮----
function test_VetoSlashRevertSlashRequestCompleted(
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_ResolverSharesHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration, 0);
⋮----
// amount1 = bound(amount1, 0, slasher.SHARES_BASE());
⋮----
// address network = alice;
// _registerNetwork(network, alice);
⋮----
// _registerOperator(alice);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _setResolverShares(alice, alice, amount1, "");
⋮----
// blockTimestamp = blockTimestamp + 3 * epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// optInServiceHints = new OptInServiceHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(new VaultHints()));
// baseSlasherHints = new BaseSlasherHints(address(baseDelegatorHints), address(optInServiceHints));
// vetoSlasherHints = VetoSlasherHints(baseSlasherHints.VETO_SLASHER_HINTS());
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// slasher.resolverSharesAt(network, alice, timestamp, "");
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
⋮----
// bytes memory hints = vetoSlasherHints.resolverSharesHint(address(slasher), network, alice, timestamp);
// slasher.resolverSharesAt(network, alice, timestamp, hints);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// function test_ResolverSharesHintNow(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// uint48 timestamp = uint48(blockTimestamp);
⋮----
// VaultHints vaultHints = new VaultHints();
// baseDelegatorHints = new BaseDelegatorHints(address(optInServiceHints), address(vaultHints));
⋮----
// slasher.resolverShares(network, alice, "");
⋮----
// slasher.resolverShares(network, alice, hints);
⋮----
// struct InputParams {
// uint256 depositAmount;
// uint256 networkLimit;
// uint256 operatorNetworkLimit;
// uint256 slashAmount;
⋮----
// function test_RequestSlashHints(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct,
// InputParams memory inputParams
// ) public {
// amount1 = bound(amount1, 1, 10 * 10 ** 18);
⋮----
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 2 * epochDuration);
// inputParams.slashAmount = bound(inputParams.slashAmount, 1, 1 * 10 ** 18);
// inputParams.depositAmount =
// bound(inputParams.depositAmount, Math.max(1, inputParams.slashAmount * hintStruct.num), 1000 * 10 ** 18);
// inputParams.networkLimit = bound(inputParams.networkLimit, inputParams.slashAmount, type(uint256).max);
// inputParams.operatorNetworkLimit =
// bound(inputParams.operatorNetworkLimit, inputParams.slashAmount, type(uint256).max);
⋮----
// VetoSlasherHintsHelper vetoSlasherHintsHelper = new VetoSlasherHintsHelper();
⋮----
// address middleware = address(vetoSlasherHintsHelper);
// _registerNetwork(network, middleware);
// _setMaxNetworkLimit(network, type(uint256).max);
⋮----
// for (uint256 i; i < hintStruct.num / 2; ++i) {
// _optInOperatorVault(alice);
// if (hintStruct.num % 2 == 0) {
// _optInOperatorNetwork(alice, address(network));
// }
//
⋮----
// _deposit(alice, inputParams.depositAmount);
// _setNetworkLimit(alice, network, inputParams.networkLimit);
// _setOperatorNetworkLimit(alice, network, alice, inputParams.operatorNetworkLimit);
⋮----
// blockTimestamp = blockTimestamp + 1;
⋮----
// vm.startPrank(alice);
// try slasher.requestSlash(network, alice, inputParams.slashAmount, uint48(blockTimestamp - 1), "")
// returns (uint256 slashIndex) {
// slasher.executeSlash(slashIndex, "");
// } catch {}
// vm.stopPrank();
⋮----
// _optOutOperatorVault(alice);
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// try vetoSlasherHintsHelper.tryRequestSlash(
// address(slasher), network, alice, inputParams.slashAmount, timestamp, ""
// ) {} catch (bytes memory data) {
// (bool reverted, uint256 gasSpent) = abi.decode(data, (bool, uint256));
// gasStruct.gasSpent1 = gasSpent;
⋮----
// bytes memory hints = vetoSlasherHints.requestSlashHints(
// address(slasher), middleware, network, alice, inputParams.slashAmount, timestamp
// );
⋮----
// address(slasher), network, alice, inputParams.slashAmount, timestamp, hints
⋮----
// gasStruct.gasSpent2 = gasSpent;
⋮----
// function test_ExecuteSlashHints(
⋮----
// hintStruct.num = bound(hintStruct.num, 1, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 1, Math.min(hintStruct.num, epochDuration));
⋮----
// inputParams.depositAmount = bound(
// inputParams.depositAmount, Math.max(1, inputParams.slashAmount * (hintStruct.num + 1)), 1000 * 10 ** 18
⋮----
// inputParams.networkLimit = bound(
// inputParams.networkLimit, Math.max(1, inputParams.slashAmount * (hintStruct.num + 1)), type(uint256).max
⋮----
// inputParams.operatorNetworkLimit = bound(
// inputParams.operatorNetworkLimit,
// Math.max(1, inputParams.slashAmount * (hintStruct.num + 1)),
// type(uint256).max
⋮----
// address middleware = alice;
⋮----
// _optInOperatorNetwork(alice, address(network));
⋮----
// _optOutOperatorNetwork(alice, address(network));
⋮----
// uint48 timestamp = uint48(blockTimestamp - hintStruct.secondsAgo);
⋮----
// vm.startPrank(middleware);
// uint256 slashIndex = slasher.requestSlash(network, alice, inputParams.slashAmount, timestamp, "");
// vm.stopPrank();
⋮----
// try vetoSlasherHintsHelper.tryExecuteSlash(address(slasher), slashIndex, "") {}
// catch (bytes memory data) {
⋮----
// bytes memory hints = vetoSlasherHints.executeSlashHints(address(slasher), address(vetoSlasherHints), slashIndex);
// try vetoSlasherHintsHelper.tryExecuteSlash(address(slasher), slashIndex, hints) {}
⋮----
// struct InputParamsVeto {
⋮----
// uint256 shares;
⋮----
// function test_VetoSlashHints(
⋮----
// InputParamsVeto memory inputParams
⋮----
// epochDuration = uint48(bound(epochDuration, 2, 7 days));
⋮----
// hintStruct.secondsAgo = 1;
⋮----
// inputParams.shares = bound(inputParams.shares, hintStruct.num * 10, 10 ** 18);
⋮----
// (vault, delegator, slasher) = _getVaultAndDelegatorAndSlasher(epochDuration, epochDuration - 1);
⋮----
// _setResolverShares(alice, address(vetoSlasherHintsHelper), inputParams.shares - (hintStruct.num - i), "");
⋮----
// // if (hintStruct.num % 2 == 0) {
// // vm.startPrank(alice);
// // try slasher.requestSlash(network, alice, inputParams.slashAmount, uint48(blockTimestamp - 1), "")
// // returns (uint256 slashIndex) {
// // slasher.executeSlash(slashIndex, "");
// // } catch {}
// // vm.stopPrank();
// // }
⋮----
// try vetoSlasherHintsHelper.tryVetoSlash(address(slasher), slashIndex, "") {}
⋮----
// bytes memory hints =
// vetoSlasherHints.vetoSlashHints(address(slasher), address(vetoSlasherHintsHelper), slashIndex);
// try vetoSlasherHintsHelper.tryVetoSlash(address(slasher), slashIndex, hints) {}
⋮----
// function test_SetResolverSharesHints(
⋮----
// address network = address(vetoSlasherHintsHelper);
⋮----
// _setResolverShares(network, alice, inputParams.shares - (hintStruct.num - i), "");
⋮----
// try vetoSlasherHintsHelper.trySetResolverShares(address(slasher), alice, inputParams.shares, "") {}
⋮----
// bytes memory hints = VetoSlasherHints(vetoSlasherHints).setResolverSharesHints(
// address(slasher), address(vetoSlasherHintsHelper), alice, inputParams.shares
⋮----
// try vetoSlasherHintsHelper.trySetResolverShares(address(slasher), alice, inputParams.shares, hints) {}
⋮----
function _getVaultAndDelegator(uint48 epochDuration) internal returns (Vault, FullRestakeDelegator) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration, uint48 vetoDuration)
⋮----
function _getSlasher(address vault_, uint48 vetoDuration) internal returns (VetoSlasher) {
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool depositWhitelist) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _requestSlash(
⋮----
function _executeSlash(address user, uint256 slashIndex, bytes memory hints)
⋮----
function _vetoSlash(address user, uint256 slashIndex, bytes memory hints) internal {
⋮----
function _setResolver(address user, uint96 identifier, address resolver, bytes memory hints) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkLimit(address user, address network, address operator, uint256 amount) internal {
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
⋮----
contract VetoSlasherHintsHelper is Test {
function tryRequestSlash(
⋮----
function tryExecuteSlash(address slasher, uint256 slashIndex, bytes memory hints) external returns (bool reverted) {
⋮----
function tryVetoSlash(address slasher, uint256 slashIndex, bytes memory hints) external returns (bool reverted) {
⋮----
function trySetResolver(address slasher, uint96 identifier, address resolver, uint256 shares, bytes memory hints)
````
## File: test/vault/Vault.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {FeeOnTransferToken} from "../mocks/FeeOnTransferToken.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract VaultTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create2(
⋮----
function test_CreateRevertInvalidEpochDuration() public {
⋮----
function test_CreateRevertInvalidCollateral(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles1(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles2(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles3(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles4(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles5(uint48 epochDuration) public {
⋮----
function test_SetDelegator() public {
⋮----
function test_SetDelegatorRevertDelegatorAlreadyInitialized() public {
⋮----
function test_SetDelegatorRevertNotDelegator() public {
⋮----
function test_SetDelegatorRevertInvalidDelegator() public {
⋮----
function test_SetSlasher() public {
⋮----
function test_SetSlasherRevertSlasherAlreadyInitialized() public {
⋮----
function test_SetSlasherRevertNotSlasher() public {
⋮----
function test_SetSlasherRevertInvalidSlasher() public {
⋮----
function test_SetSlasherZeroAddress() public {
⋮----
function test_DepositTwice(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositTwiceFeeOnTransferCollateral(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositBoth(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositRevertInvalidOnBehalfOf(uint256 amount1) public {
⋮----
function test_DepositRevertInsufficientDeposit() public {
⋮----
function test_WithdrawTwice(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
// uint48 epochDuration = 1;
⋮----
function test_WithdrawRevertInvalidClaimer(uint256 amount1) public {
⋮----
function test_WithdrawRevertInsufficientWithdrawal(uint256 amount1) public {
⋮----
function test_WithdrawRevertTooMuchWithdraw(uint256 amount1) public {
⋮----
function test_RedeemTwice(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_RedeemRevertInvalidClaimer(uint256 amount1) public {
⋮----
function test_RedeemRevertInsufficientRedeemption(uint256 amount1) public {
⋮----
function test_RedeemRevertTooMuchRedeem(uint256 amount1) public {
⋮----
function test_Claim(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInvalidRecipient(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInvalidEpoch(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertAlreadyClaimed(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInsufficientClaim(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimBatch(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidRecipient(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidLengthEpochs(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidEpoch(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertAlreadyClaimed(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInsufficientClaim(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_SetDepositWhitelist() public {
⋮----
function test_SetDepositWhitelistRevertNotWhitelistedDepositor() public {
⋮----
function test_SetDepositWhitelistRevertAlreadySet() public {
⋮----
function test_SetDepositorWhitelistStatus() public {
⋮----
function test_SetDepositorWhitelistStatusRevertInvalidAccount() public {
⋮----
function test_SetDepositorWhitelistStatusRevertAlreadySet() public {
⋮----
function test_SetIsDepositLimit() public {
⋮----
function test_SetIsDepositLimitRevertAlreadySet() public {
⋮----
function test_SetDepositLimit(uint256 limit1, uint256 limit2, uint256 depositAmount) public {
⋮----
function test_SetDepositLimitToNull(uint256 limit1) public {
⋮----
function test_SetDepositLimitRevertDepositLimitReached(uint256 depositAmount, uint256 limit) public {
⋮----
function test_SetDepositLimitRevertAlreadySet(uint256 limit) public {
⋮----
function test_OnSlashRevertNotSlasher() public {
⋮----
function test_Slash(
// uint48 epochDuration,
⋮----
// epochDuration = uint48(bound(epochDuration, 2, 10 days));
⋮----
// address network = alice;
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_ActiveSharesHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// vault = _getVault(epochDuration);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _deposit(alice, amount1);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// VaultHints vaultHints = new VaultHints();
// bytes memory hint = vaultHints.activeSharesHint(address(vault), timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// vault.activeSharesAt(timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// vault.activeSharesAt(timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertApproxEqRel(gasStruct.gasSpent1, gasStruct.gasSpent2, 0.05e18);
⋮----
// function test_ActiveStakeHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// bytes memory hint = vaultHints.activeStakeHint(address(vault), timestamp);
⋮----
// vault.activeStakeAt(timestamp, new bytes(0));
⋮----
// vault.activeStakeAt(timestamp, hint);
⋮----
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// function test_ActiveSharesOfHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// bytes memory hint = vaultHints.activeSharesOfHint(address(vault), alice, timestamp);
⋮----
// vault.activeSharesOfAt(alice, timestamp, new bytes(0));
⋮----
// vault.activeSharesOfAt(alice, timestamp, hint);
⋮----
// struct ActiveBalanceOfHintsUint32 {
// uint32 activeSharesOfHint;
// uint32 activeStakeHint;
// uint32 activeSharesHint;
⋮----
// function test_ActiveBalanceOfHint(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct,
// ActiveBalanceOfHintsUint32 memory activeBalanceOfHintsUint32
// ) public {
⋮----
// bytes memory hint = vaultHints.activeBalanceOfHints(address(vault), alice, timestamp);
⋮----
// bytes memory activeBalanceOfHints = abi.encode(
// IVault.ActiveBalanceOfHints({
// activeSharesOfHint: abi.encode(activeBalanceOfHintsUint32.activeSharesOfHint),
// activeStakeHint: abi.encode(activeBalanceOfHintsUint32.activeStakeHint),
// activeSharesHint: abi.encode(activeBalanceOfHintsUint32.activeSharesHint)
// })
// );
// try vault.activeBalanceOfAt(alice, timestamp, activeBalanceOfHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// vault.activeBalanceOfAt(alice, timestamp, "");
⋮----
// vault.activeBalanceOfAt(alice, timestamp, hint);
⋮----
// function test_ActiveBalanceOfHintMany(
⋮----
// HintStruct memory hintStruct
⋮----
// amount1 = bound(amount1, 1, 1 * 10 ** 18);
⋮----
// hintStruct.num = 500;
⋮----
// vault.activeBalanceOfAt(alice, timestamp, "");
⋮----
// assertLt(gasStruct.gasSpent1 - gasStruct.gasSpent2, 10_000);
⋮----
function _getVault(uint48 epochDuration) internal returns (Vault) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _grantIsDepositLimitSetRole(address user, address account) internal {
⋮----
function _grantDepositLimitSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _redeem(address user, uint256 shares) internal returns (uint256 withdrawnAssets, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool status) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setIsDepositLimit(address user, bool status) internal {
⋮----
function _setDepositLimit(address user, uint256 amount) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkLimit(address user, address network, address operator, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
````
## File: test/vault/VaultTokenized.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../../src/contracts/service/OptInService.sol";
⋮----
import {VaultTokenized} from "../../src/contracts/vault/VaultTokenized.sol";
import {NetworkRestakeDelegator} from "../../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../../src/interfaces/vault/IVault.sol";
import {IVaultTokenized} from "../../src/interfaces/vault/IVaultTokenized.sol";
⋮----
import {Token} from "../mocks/Token.sol";
import {FeeOnTransferToken} from "../mocks/FeeOnTransferToken.sol";
import {VaultConfigurator} from "../../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
import {IVaultStorage} from "../../src/interfaces/vault/IVaultStorage.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
import {VaultHints} from "../../src/contracts/hints/VaultHints.sol";
import {Subnetwork} from "../../src/contracts/libraries/Subnetwork.sol";
⋮----
contract VaultTokenizedTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create2(
⋮----
// Bound parameters
⋮----
// Setup block timestamp
⋮----
// Create role holders
⋮----
// Create vault and delegator
⋮----
// Test role constants
⋮----
// Test vault properties
⋮----
// Test epoch functionality
⋮----
// Test stake and shares
⋮----
// Test withdrawals
⋮----
// Test whitelist and slashing
⋮----
// Test initialization status
⋮----
// Test epoch transitions
⋮----
// Test ERC20 functionality
⋮----
function test_CreateRevertInvalidEpochDuration() public {
⋮----
function test_CreateRevertInvalidCollateral(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles1(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles2(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles3(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles4(uint48 epochDuration) public {
⋮----
function test_CreateRevertMissingRoles5(uint48 epochDuration) public {
⋮----
function test_SetDelegator() public {
⋮----
function test_SetDelegatorRevertDelegatorAlreadyInitialized() public {
⋮----
function test_SetDelegatorRevertNotDelegator() public {
⋮----
function test_SetDelegatorRevertInvalidDelegator() public {
⋮----
function test_SetSlasher() public {
⋮----
function test_SetSlasherRevertSlasherAlreadyInitialized() public {
⋮----
function test_SetSlasherRevertNotSlasher() public {
⋮----
function test_SetSlasherRevertInvalidSlasher() public {
⋮----
function test_SetSlasherZeroAddress() public {
⋮----
function test_DepositTwice(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositTwiceFeeOnTransferCollateral(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositBoth(uint256 amount1, uint256 amount2) public {
⋮----
function test_DepositRevertInvalidOnBehalfOf(uint256 amount1) public {
⋮----
function test_DepositRevertInsufficientDeposit() public {
⋮----
function test_WithdrawTwice(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
// uint48 epochDuration = 1;
⋮----
function test_WithdrawRevertInvalidClaimer(uint256 amount1) public {
⋮----
function test_WithdrawRevertInsufficientWithdrawal(uint256 amount1) public {
⋮----
function test_WithdrawRevertTooMuchWithdraw(uint256 amount1) public {
⋮----
function test_RedeemTwice(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_RedeemRevertInvalidClaimer(uint256 amount1) public {
⋮----
function test_RedeemRevertInsufficientRedeemption(uint256 amount1) public {
⋮----
function test_RedeemRevertTooMuchRedeem(uint256 amount1) public {
⋮----
function test_Claim(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInvalidRecipient(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInvalidEpoch(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertAlreadyClaimed(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRevertInsufficientClaim(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimBatch(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidRecipient(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidLengthEpochs(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInvalidEpoch(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertAlreadyClaimed(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_ClaimBatchRevertInsufficientClaim(uint256 amount1, uint256 amount2, uint256 amount3) public {
⋮----
function test_SetDepositWhitelist() public {
⋮----
function test_SetDepositWhitelistRevertNotWhitelistedDepositor() public {
⋮----
function test_SetDepositWhitelistRevertAlreadySet() public {
⋮----
function test_SetDepositorWhitelistStatus() public {
⋮----
function test_SetDepositorWhitelistStatusRevertInvalidAccount() public {
⋮----
function test_SetDepositorWhitelistStatusRevertAlreadySet() public {
⋮----
function test_SetIsDepositLimit() public {
⋮----
function test_SetIsDepositLimitRevertAlreadySet() public {
⋮----
function test_SetDepositLimit(uint256 limit1, uint256 limit2, uint256 depositAmount) public {
⋮----
function test_SetDepositLimitToNull(uint256 limit1) public {
⋮----
function test_SetDepositLimitRevertDepositLimitReached(uint256 depositAmount, uint256 limit) public {
⋮----
function test_SetDepositLimitRevertAlreadySet(uint256 limit) public {
⋮----
function test_OnSlashRevertNotSlasher() public {
⋮----
function test_Slash(
// uint48 epochDuration,
⋮----
// epochDuration = uint48(bound(epochDuration, 2, 10 days));
⋮----
// address network = alice;
⋮----
// struct GasStruct {
// uint256 gasSpent1;
// uint256 gasSpent2;
// }
⋮----
// struct HintStruct {
// uint256 num;
// bool back;
// uint256 secondsAgo;
⋮----
// function test_ActiveSharesHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
// amount1 = bound(amount1, 1, 100 * 10 ** 18);
// epochDuration = uint48(bound(epochDuration, 1, 7 days));
// hintStruct.num = bound(hintStruct.num, 0, 25);
// hintStruct.secondsAgo = bound(hintStruct.secondsAgo, 0, 1_720_700_948);
⋮----
// uint256 blockTimestamp = vm.getBlockTimestamp();
// blockTimestamp = blockTimestamp + 1_720_700_948;
// vm.warp(blockTimestamp);
⋮----
// vault = _getVault(epochDuration);
⋮----
// for (uint256 i; i < hintStruct.num; ++i) {
// _deposit(alice, amount1);
⋮----
// blockTimestamp = blockTimestamp + epochDuration;
// vm.warp(blockTimestamp);
// }
⋮----
// uint48 timestamp =
// uint48(hintStruct.back ? blockTimestamp - hintStruct.secondsAgo : blockTimestamp + hintStruct.secondsAgo);
⋮----
// VaultHints vaultHints = new VaultHints();
// bytes memory hint = vaultHints.activeSharesHint(address(vault), timestamp);
⋮----
// GasStruct memory gasStruct = GasStruct({gasSpent1: 1, gasSpent2: 1});
// vault.activeSharesAt(timestamp, new bytes(0));
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// vault.activeSharesAt(timestamp, hint);
// gasStruct.gasSpent2 = vm.lastCallGas().gasTotalUsed;
// assertApproxEqRel(gasStruct.gasSpent1, gasStruct.gasSpent2, 0.05e18);
⋮----
// function test_ActiveStakeHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// bytes memory hint = vaultHints.activeStakeHint(address(vault), timestamp);
⋮----
// vault.activeStakeAt(timestamp, new bytes(0));
⋮----
// vault.activeStakeAt(timestamp, hint);
⋮----
// assertGe(gasStruct.gasSpent1, gasStruct.gasSpent2);
⋮----
// function test_ActiveSharesOfHint(uint256 amount1, uint48 epochDuration, HintStruct memory hintStruct) public {
⋮----
// bytes memory hint = vaultHints.activeSharesOfHint(address(vault), alice, timestamp);
⋮----
// vault.activeSharesOfAt(alice, timestamp, new bytes(0));
⋮----
// vault.activeSharesOfAt(alice, timestamp, hint);
⋮----
// struct ActiveBalanceOfHintsUint32 {
// uint32 activeSharesOfHint;
// uint32 activeStakeHint;
// uint32 activeSharesHint;
⋮----
// function test_ActiveBalanceOfHint(
// uint256 amount1,
// uint48 epochDuration,
// HintStruct memory hintStruct,
// ActiveBalanceOfHintsUint32 memory activeBalanceOfHintsUint32
// ) public {
⋮----
// bytes memory hint = vaultHints.activeBalanceOfHints(address(vault), alice, timestamp);
⋮----
// bytes memory activeBalanceOfHints = abi.encode(
// IVault.ActiveBalanceOfHints({
// activeSharesOfHint: abi.encode(activeBalanceOfHintsUint32.activeSharesOfHint),
// activeStakeHint: abi.encode(activeBalanceOfHintsUint32.activeStakeHint),
// activeSharesHint: abi.encode(activeBalanceOfHintsUint32.activeSharesHint)
// })
// );
// try vault.activeBalanceOfAt(alice, timestamp, activeBalanceOfHints) {
// gasStruct.gasSpent1 = vm.lastCallGas().gasTotalUsed;
// } catch {
// vault.activeBalanceOfAt(alice, timestamp, "");
⋮----
// vault.activeBalanceOfAt(alice, timestamp, hint);
⋮----
// function test_ActiveBalanceOfHintMany(
⋮----
// HintStruct memory hintStruct
⋮----
// amount1 = bound(amount1, 1, 1 * 10 ** 18);
⋮----
// hintStruct.num = 500;
⋮----
// vault.activeBalanceOfAt(alice, timestamp, "");
⋮----
// assertLt(gasStruct.gasSpent1 - gasStruct.gasSpent2, 10_000);
⋮----
function test_Transfer(uint256 amount1, uint256 amount2) public {
⋮----
function _getVault(uint48 epochDuration) internal returns (VaultTokenized) {
⋮----
function _getVaultAndDelegatorAndSlasher(uint48 epochDuration)
⋮----
// Set parameters
⋮----
// Create vault, delegator, and slasher
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(address user, address account) internal {
⋮----
function _grantIsDepositLimitSetRole(address user, address account) internal {
⋮----
function _grantDepositLimitSetRole(address user, address account) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _redeem(address user, uint256 shares) internal returns (uint256 withdrawnAssets, uint256 mintedShares) {
⋮----
function _claim(address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(address user) internal {
⋮----
function _optOutOperatorVault(address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(address user, bool status) internal {
⋮----
function _setDepositorWhitelistStatus(address user, address depositor, bool status) internal {
⋮----
function _setIsDepositLimit(address user, bool status) internal {
⋮----
function _setDepositLimit(address user, uint256 amount) internal {
⋮----
function _setNetworkLimit(address user, address network, uint256 amount) internal {
⋮----
function _setOperatorNetworkLimit(address user, address network, address operator, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal {
````
## File: test/DelegatorFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "./mocks/Token.sol";
import {VaultConfigurator} from "../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../src/interfaces/slasher/ISlasher.sol";
⋮----
contract DelegatorFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/NetworkRegistry.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {NetworkRegistry} from "../src/contracts/NetworkRegistry.sol";
import {INetworkRegistry} from "../src/interfaces/INetworkRegistry.sol";
⋮----
contract NetworkRegistryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_Register() public {
⋮----
function test_RegisterRevertEntityAlreadyRegistered() public {
````
## File: test/OperatorRegistry.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {OperatorRegistry} from "../src/contracts/OperatorRegistry.sol";
import {IOperatorRegistry} from "../src/interfaces/IOperatorRegistry.sol";
⋮----
contract OperatorRegistryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_Register() public {
⋮----
function test_RegisterRevertEntityAlreadyRegistered() public {
````
## File: test/POC.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "./POCBase.t.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Subnetwork} from "../src/contracts/libraries/Subnetwork.sol";
⋮----
contract POCTest is POCBaseTest {
⋮----
function setUp() public override {
// There are 4 initially deployed Vaults:
// 1. With NetworkRestakeDelegator, with Slasher - 7 days vault epoch (can be used with vault1, delegator1, slasher1 variables)
// 2. With FullRestakeDelegator, with Slasher - 7 days vault epoch (can be used with vault2, delegator2, slasher2 variables)
// 3. With NetworkRestakeDelegator, with VetoSlasher - 7 days vault epoch, 1 day veto period (can be used with vault3, delegator3, slasher3 variables)
// 4. With FullRestakeDelegator, with VetoSlasher - 7 days vault epoch, 1 day veto period (can be used with vault4, delegator4, slasher4 variables)
// For other deployments or interacting with these ones, you may use predefined functions in the POCBaseTest contract.
⋮----
function test_POC() public {}
````
## File: test/POCBase.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {IVaultFactory} from "../src/interfaces/IVaultFactory.sol";
import {IDelegatorFactory} from "../src/interfaces/IDelegatorFactory.sol";
import {ISlasherFactory} from "../src/interfaces/ISlasherFactory.sol";
import {INetworkRegistry} from "../src/interfaces/INetworkRegistry.sol";
import {IOperatorRegistry} from "../src/interfaces/IOperatorRegistry.sol";
import {IMetadataService} from "../src/interfaces/service/IMetadataService.sol";
import {INetworkMiddlewareService} from "../src/interfaces/service/INetworkMiddlewareService.sol";
import {IOptInService} from "../src/interfaces/service/IOptInService.sol";
⋮----
import {IBaseDelegator} from "../src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "../src/interfaces/slasher/IBaseSlasher.sol";
import {IVault} from "../src/interfaces/vault/IVault.sol";
import {IVaultTokenized} from "../src/interfaces/vault/IVaultTokenized.sol";
import {INetworkRestakeDelegator} from "../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IOperatorSpecificDelegator} from "../src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IOperatorNetworkSpecificDelegator} from "../src/interfaces/delegator/IOperatorNetworkSpecificDelegator.sol";
import {ISlasher} from "../src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "../src/interfaces/slasher/IVetoSlasher.sol";
⋮----
import {IVaultConfigurator} from "../src/interfaces/IVaultConfigurator.sol";
⋮----
import {Token} from "./mocks/Token.sol";
import {FeeOnTransferToken} from "./mocks/FeeOnTransferToken.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
⋮----
import {Subnetwork} from "../src/contracts/libraries/Subnetwork.sol";
import "./integration/SymbioticCoreBytecode.sol";
⋮----
contract POCBaseTest is Test {
⋮----
function setUp() public virtual {
⋮----
function _deployCreate2(bytes32 salt, bytes memory baseCode, bytes memory constructorArgs)
⋮----
// Copy `baseCode` one word at a time, backwards.
⋮----
o := add(o, w) // `sub(o, 0x20)`.
⋮----
// Copy `constructorArgs` one word at a time, backwards.
⋮----
mstore(last, 0) // Zeroize the slot after the bytes.
mstore(creationCode, totalLen) // Store the length.
mstore(0x40, add(last, 0x20)) // Allocate memory.
⋮----
function _getVault(uint48 epochDuration) internal returns (IVault) {
⋮----
function _getVaultAndNetworkRestakeDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getVaultAndFullRestakeDelegatorAndSlasher(uint48 epochDuration)
⋮----
function _getVaultAndNetworkRestakeDelegatorAndVetoSlasher(uint48 epochDuration, uint48 vetoDuration)
⋮----
function _getVaultAndFullRestakeDelegatorAndVetoSlasher(uint48 epochDuration, uint48 vetoDuration)
⋮----
function _registerOperator(address user) internal {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _grantDepositorWhitelistRole(IVault vault, address user, address account) internal {
⋮----
function _grantDepositWhitelistSetRole(IVault vault, address user, address account) internal {
⋮----
function _grantIsDepositLimitSetRole(IVault vault, address user, address account) internal {
⋮----
function _grantDepositLimitSetRole(IVault vault, address user, address account) internal {
⋮----
function _deposit(IVault vault, address user, uint256 amount)
⋮----
function _withdraw(IVault vault, address user, uint256 amount)
⋮----
function _redeem(IVault vault, address user, uint256 shares)
⋮----
function _claim(IVault vault, address user, uint256 epoch) internal returns (uint256 amount) {
⋮----
function _claimBatch(IVault vault, address user, uint256[] memory epochs) internal returns (uint256 amount) {
⋮----
function _optInOperatorVault(IVault vault, address user) internal {
⋮----
function _optOutOperatorVault(IVault vault, address user) internal {
⋮----
function _optInOperatorNetwork(address user, address network) internal {
⋮----
function _optOutOperatorNetwork(address user, address network) internal {
⋮----
function _setDepositWhitelist(IVault vault, address user, bool status) internal {
⋮----
function _setDepositorWhitelistStatus(IVault vault, address user, address depositor, bool status) internal {
⋮----
function _setIsDepositLimit(IVault vault, address user, bool status) internal {
⋮----
function _setDepositLimit(IVault vault, address user, uint256 amount) internal {
⋮----
function _setNetworkLimitNetwork(INetworkRestakeDelegator delegator, address user, address network, uint256 amount)
⋮----
function _setNetworkLimitFull(IFullRestakeDelegator delegator, address user, address network, uint256 amount)
⋮----
function _setOperatorNetworkShares(
⋮----
function _setOperatorNetworkLimit(
⋮----
function _setMaxNetworkLimit(address delegator, address user, uint96 identifier, uint256 amount) internal {
⋮----
function _slash(
⋮----
function _requestSlash(
⋮----
function _executeSlash(IVetoSlasher slasher, address user, uint256 slashIndex, bytes memory hints)
⋮----
function _vetoSlash(IVetoSlasher slasher, address user, uint256 slashIndex, bytes memory hints) internal {
⋮----
function _setResolver(IVetoSlasher slasher, address user, uint96 identifier, address resolver, bytes memory hints)
````
## File: test/SlasherFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "./mocks/Token.sol";
import {VaultConfigurator} from "../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../src/interfaces/delegator/IBaseDelegator.sol";
import {IVetoSlasher} from "../src/interfaces/slasher/IVetoSlasher.sol";
import {IBaseSlasher} from "../src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "../src/interfaces/slasher/ISlasher.sol";
⋮----
contract SlasherFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/VaultConfigurator.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "./mocks/Token.sol";
import {VaultConfigurator} from "../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
contract VaultConfiguratorTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(
````
## File: test/VaultFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "../src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "../src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "../src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "../src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "../src/contracts/OperatorRegistry.sol";
import {MetadataService} from "../src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "../src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "../src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "../src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "../src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "../src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "../src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from "../src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "../src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "../src/contracts/slasher/VetoSlasher.sol";
⋮----
import {IVault} from "../src/interfaces/vault/IVault.sol";
⋮----
import {Token} from "./mocks/Token.sol";
import {VaultConfigurator} from "../src/contracts/VaultConfigurator.sol";
import {IVaultConfigurator} from "../src/interfaces/IVaultConfigurator.sol";
import {INetworkRestakeDelegator} from "../src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IFullRestakeDelegator} from "../src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IBaseDelegator} from "../src/interfaces/delegator/IBaseDelegator.sol";
import {ISlasher} from "../src/interfaces/slasher/ISlasher.sol";
import {IBaseSlasher} from "../src/interfaces/slasher/IBaseSlasher.sol";
⋮----
contract VaultFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: .env.example
````
ETH_RPC_URL=
ETHERSCAN_API_KEY=
````
## File: .gitignore
````
# Compiler files
cache/
out/**/
# Ignore node_modules and dependencies
node_modules
*.log
yarn-error.log
# Ignore build outputs
dist
out
**/__pycache__
# Ignore environment files
.env
# Ignore version control files
docs/autogen/.git
docs/autogen/.gitignore
# Ignore editor and OS-specific files
*.swp
*.DS_Store
Thumbs.db
# Ignore IDE-specific files
.idea/
.vscode/
cache/
out/
broadcast/
deployments/
script/logs.txt
lcov.info
/target
/coverage
/report
.password
````
## File: .gitmodules
````
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
````
## File: .pre-commit-config.yaml
````yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: mixed-line-ending
args: ["--fix=lf"]
exclude: "^(docs/autogen|snapshots/)"
- id: trailing-whitespace
exclude: "^(docs/autogen|snapshots/)"
- id: end-of-file-fixer
exclude: "^(docs/autogen|snapshots/)"
- id: check-merge-conflict
- id: check-json
exclude: "^(docs/autogen|snapshots/)"
- id: check-yaml
- repo: local
hooks:
- id: sort-imports
name: Sort imports
description: Normalize and sort import statements in Solidity files
language: system
entry: python3 script/utils/sort_imports.py
files: "^(src|examples)/.*\\.sol$"
pass_filenames: true
- id: sort-errors
name: Sort solidity errors
description: Alphabetize error declarations in Solidity files
language: system
entry: python3 script/utils/sort_errors.py
files: "^(src|examples)/.*\\.sol$"
pass_filenames: true
- id: format
name: Format solidity code
description: Format solidity code with `forge fmt`
language: system
entry: forge fmt
files: '\.sol$'
exclude: "^lib/"
pass_filenames: true
- id: doc
name: Generate documentation
description: Generate docs with `forge doc`
language: system
entry: bash -lc 'forge build; rm -rf docs/autogen; forge doc -b -o docs/autogen'
pass_filenames: false
- id: forge-snapshots
name: Update forge snapshots
language: system
entry: bash -lc 'mkdir -p snapshots; forge build; forge build --sizes | tee snapshots/sizes.txt >/dev/null; forge test --isolate --gas-report | tee snapshots/gas.txt >/dev/null'
pass_filenames: false
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
name: Format non-solidity files with prettier
exclude: "^(docs/autogen|snapshots/)"
````
## File: .prettierignore
````
foundry.toml
out
lib/
cache/
docs/autogenerated
*.sol
deployments/
snapshots/
````
## File: .prettierrc
````
{
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": true,
"trailingComma": "all",
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false
}
},
{
"files": "*.json",
"options": {
"tabWidth": 4
}
}
]
}
````
## File: CONTRIBUTING.md
````markdown
# Contributing
- [Install](#install)
- [Pre-commit Hooks](#pre-commit-hooks)
- [Requirements for merge](#requirements-for-merge)
- [Branching](#branching)
- [Main](#main)
- [Audit](#audit)
- [Code Practices](#code-practices)
- [Code Style](#code-style)
- [Solidity Versioning](#solidity-versioning)
- [Interfaces](#interfaces)
- [NatSpec \& Comments](#natspec--comments)
- [Testing](#testing)
- [Best Practices](#best-practices)
- [IR Compilation](#ir-compilation)
- [Gas Metering](#gas-metering)
- [Deployment](#deployment)
- [Bytecode Hash](#bytecode-hash)
- [Dependency Management](#dependency-management)
- [Releases](#releases)
## Install
Follow these steps to set up your local environment for development:
- [Install foundry](https://book.getfoundry.sh/getting-started/installation)
- Install dependencies: `forge install`
- [Install pre-commit](https://pre-commit.com/#installation)
- Install pre commit hooks: `pre-commit install`
## Pre-commit Hooks
Follow the [installation steps](#install) to enable pre-commit hooks. To ensure consistency in our formatting `pre-commit` is used to check whether code was formatted properly and the documentation is up to date. Whenever a commit does not meet the checks implemented by pre-commit, the commit will fail and the pre-commit checks will modify the files to make the commits pass. Include these changes in your commit for the next commit attempt to succeed. On pull requests the CI checks whether all pre-commit hooks were run correctly.
This repo includes the following pre-commit hooks that are defined in the `.pre-commit-config.yaml`:
- `mixed-line-ending`: This hook ensures that all files have the same line endings (LF).
- `trailing-whitespace`: Strips trailing spaces from lines so that diffs remain clean and editors don't introduce noise.
- `end-of-file-fixer`: Ensures every file ends with a single newline and removes extra blank lines at the end of files.
- `check-merge-conflict`: Fails when Git merge conflict markers are present to avoid committing unresolved conflicts.
- `check-json`: Validates JSON files and fails fast on malformed syntax.
- `check-yaml`: Parses YAML files to verify they are syntactically valid.
- `sort-imports`: Normalises and sorts imports according to the rules mentioned in the [Code Style](#code-style) below.
- `sort-errors`: Sorts errors according to the rules mentioned in the [Code Style](#code-style) below.
- `format`: This hook uses `forge fmt` to format all Solidity files.
- `doc`: This hook uses `forge doc` to generate the Solidity documentation. Commit the generated files whenever the documentation changes.
- `prettier`: All remaining files are formatted using prettier.
## Requirements for merge
In order for a PR to be merged, it must pass the following requirements:
- All commits within the PR must be signed
- CI must pass (tests, linting, etc.)
- New features must be merged with associated tests
- Bug fixes must have a corresponding test that fails without the fix
- The PR must be approved by at least one maintainer
## Branching
This section outlines the branching strategy of this repo.
### Main
The main branch is supposed to reflect the deployed state on all networks, if not indicated otherwise inside the README. Only audited code should be merged into main. Сommits from dev branches should be merged into the main branch using a regular merge strategy. The commit messages should follow [the Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/).
### Audit
Before an audit, the code should be frozen on a branch dedicated to the audit with the naming convention `audit/`. Each fix in response to an audit finding should be developed as a separate commit. The commit message should look similar to `fix: - `.
## Code Practices
### Code Style
The repo follows the official [Solidity Style Guide](https://docs.soliditylang.org/en/latest/style-guide.html). In addition to that, this repo also borrows the following rules from [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/GUIDELINES.md#solidity-conventions):
- Internal or private state variables or functions should have an underscore prefix.
```solidity
contract TestContract {
uint256 private _privateVar;
uint256 internal _internalVar;
function _testInternal() internal { ... }
function _testPrivate() private { ... }
}
```
- Naming collisions should be avoided using a single trailing underscore.
```solidity
contract TestContract {
uint256 public foo;
constructor(uint256 foo_) {
foo = foo_;
}
}
```
- Interface names should have a capital I prefix.
```solidity
interface IERC777 {
```
- Contracts not intended to be used standalone should be marked abstract, so they are required to be inherited by other contracts.
```solidity
abstract contract AccessControl is ..., {
```
- Unchecked arithmetic blocks should contain comments explaining why overflow is guaranteed not to happen or is permissible. If the reason is immediately apparent from the line above the unchecked block, the comment may be omitted.
Also, such exceptions/additions exist:
- Functions should be grouped according to their visibility and ordered:
1. constructor
2. external
3. public
4. internal
5. private
6. receive function (if exists)
7. fallback function (if exists)
- Each contract should be virtually divided into sections by using such separators:
1. /\* CONSTANTS \*/
2. /\* IMMUTABLES \*/
3. /\* STATE VARIABLES \*/
4. /\* MODIFIERS \*/
5. /\* CONSTRUCTOR \*/
6. /\* EXTERNAL FUNCTIONS \*/
7. /\* PUBLIC FUNCTIONS \*/
8. /\* INTERNAL FUNCTIONS \*/
9. /\* PRIVATE FUNCTIONS \*/
10. /\* RECEIVE FUNCTION \*/
11. /\* FALLBACK FUNCTION \*/
- Each interface should be virtually divided into sections by using such separators:
1. /\* ERRORS \*/
2. /\* STRUCTS \*/
3. /\* EVENTS \*/
4. /\* FUNCTIONS \*/
- Do not use external and private visibilities in most cases.
- Events should generally be emitted immediately after the state change that they
represent, and should be named the same as the function's name. Some exceptions may be made for gas
efficiency if the result doesn't affect the observable ordering of events.
```solidity
function _burn(address who, uint256 value) internal {
super._burn(who, value);
emit Burn(who, value);
}
```
- Custom errors should be used whenever possible. The naming should be concise and easy to read.
- Imports should be divided into separate groups and ordered alphabetically ascending inside each group:
1. contracts
2. libraries
3. interfaces
4. external files separately
```solidity
import {NetworkManager} from "../base/NetworkManager.sol";
import {OzEIP712} from "../base/OzEIP712.sol";
import {PermissionManager} from "../base/PermissionManager.sol";
import {Checkpoints} from "../../libraries/structs/Checkpoints.sol";
import {KeyTags} from "../../libraries/utils/KeyTags.sol";
import {ISettlement} from "../interfaces/modules/settlement/ISettlement.sol";
import {ISigVerifier} from "../interfaces/modules/settlement/sig-verifiers/ISigVerifier.sol";
import {StaticDelegateCallable} from "@symbioticfi/core/src/contracts/common/StaticDelegateCallable.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
```
- In case of comparison with `msg.sender` or `tx.origin`, these keywords should be on the right side of the inequality.
```solidity
modifier onlyOwner() internal {
if (owner != msg.sender) {
revert NotOwner();
}
}
```
- Errors should be ordered alphabetically ascending.
```solidity
error InsufficientFunds();
error NoAccess();
error NotOwner();
```
### Solidity Versioning
Contracts that are meant to be deployed should have an explicit version set in the `pragma` statement.
```solidity
pragma solidity 0.8.X;
```
Abstract contracts, libraries and interfaces should use the caret (`^`) range operator to specify the version range to ensure better compatibility.
```solidity
pragma solidity ^0.X.0;
```
Libraries and abstract contracts using functionality introduced in newer versions of Solidity can use caret range operators with higher path versions (e.g., `^0.8.24` when using transient storage opcodes). For interfaces, it should be considered to use the greater than or equal to (`>=`) range operator to ensure better compatibility with future versions of Solidity.
### Interfaces
Every contract MUST implement its corresponding interface that includes all externally callable functions, errors and events.
### NatSpec & Comments
Interfaces should be the entry point for all contracts. When exploring a contract within the repository, the interface MUST contain all relevant information to understand the functionality of the contract in the form of NatSpec comments. This includes all externally callable functions, structs, errors and events. The NatSpec documentation MUST be added to the functions, structs, errors and events within the interface. This allows a reader to understand the functionality of a function before moving on to the implementation. The implementing functions MUST point to the NatSpec documentation in the interface using `@inheritdoc`. Internal and private functions shouldn't have NatSpec documentation except for `@dev` comments, whenever more context is needed. Additional comments within a function should only be used to give more context to more complex operations; otherwise, the code should be kept readable and self-explanatory. NatSpec comments in contracts should use a triple slash (`///`) to bring less noise to the implementation, while libraries and interfaces should use `/* */` wrappers.
The comments should respect the following rules:
- For read functions: `@notice Returns <...>`
- For write functions: `@notice `
- For structs: `@notice `
- For errors: `@notice Raised when <...>`
- For events: `@notice Emitted when <...>`
Each contract/library/interface should have a title comment that should follow such a structure:
1. `@title ` (e.g., `Vault`)
2. `@notice Contract/Library/Interface for <...>.` - also, other variations are possible, e.g.:
- `@notice Interface for the Vault contract.`
- `@notice Base contract for <...>.`
- `@notice Library-logic for <...>.`
3. `@dev <...>` (optional)
## Testing
The following testing practices should be followed when writing unit tests for new code. All functions, lines and branches should be tested to result in 100% testing coverage. Fuzz parameters and conditions whenever possible. Extremes should be tested in dedicated edge case and corner case tests. Invariants should be tested in dedicated invariant tests.
Differential testing should be used to compare assembly implementations with implementations in Solidity or testing alternative implementations against existing Solidity or non-Solidity code using ffi.
New features must be merged with associated tests. Bug fixes should have a corresponding test that fails without the bug fix.
### Best Practices
Best practices and naming conventions should be followed as outlined in the [Foundry Book](https://getfoundry.sh/forge/tests/overview).
### IR Compilation
All contracts and tests should be compilable without IR whenever possible.
### Gas Metering
Gas for function calls should be metered using the built-in `vm.snapshotGasLastCall` function in forge. To meter across multiple calls `vm.startSnapshotGas` and `vm.stopSnapshotGas` can be used. Tests that measure gas should be annotated with `/// forge-config: default.isolate = true` and not be fuzzed to ensure that the gas snapshot is accurate and consistent for CI verification. All external functions should have a gas snapshot test, and diverging paths within a function should have appropriate gas snapshot tests.
For more information on gas metering, see the [Forge cheatcodes reference](https://getfoundry.sh/reference/cheatcodes/gas-snapshots/#snapshotgas-cheatcodes).
### Bytecode Hash
Bytecode hash should be set to `none` in the `foundry.toml` file to ensure that the bytecode is consistent.
## Dependency Management
The preferred way to manage dependencies is using [`forge install`](https://book.getfoundry.sh/forge/dependencies). This ensures that your project uses the correct versions and structure for all external libraries. Also, `npm` and `soldeer` packages should be published to increase coverage of different use-cases.
## Releases
Every deployment and change made to contracts after deployment should be accompanied by a tag and release on GitHub.
````
## File: foundry.lock
````
{
"lib/forge-std": {
"rev": "8e40513d678f392f398620b3ef2b418648b33e89"
},
"lib/openzeppelin-contracts": {
"rev": "dbb6104ce834628e473d2173bbc9d47f81a9eec3"
},
"lib/openzeppelin-contracts-upgradeable": {
"rev": "723f8cab09cdae1aca9ec9cc1cfa040c2d4b06c1"
}
}
````
## File: foundry.toml
````toml
[profile.default]
evm_version = "cancun"
solc = "0.8.25"
optimizer = true
optimizer_runs = 200
via_ir = true
src = "src"
out = "out"
libs = ["lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
gas_reports = ["*"]
gas_limit = "18446744073709551615"
dynamic_test_linking = true
ignored_warnings_from = ["test/","script/"]
ffi = true
[rpc_endpoints]
mainnet = "${ETH_RPC_URL}"
hoodi = "${ETH_RPC_URL_HOODI}"
holesky = "${ETH_RPC_URL_HOLESKY}"
sepolia = "${ETH_RPC_URL_SEPOLIA}"
[fmt]
bracket_spacing = false
int_types = "long"
line_length = 120
multiline_func_header = "attributes_first"
number_underscore = "thousands"
quote_style = "double"
tab_width = 4
single_line_statement_blocks = "preserve"
sort_imports = false
contract_new_lines = false
override_spacing = false
hex_underscore = "preserve"
wrap_comments = false
[lint]
lint_on_build = false
exclude_lints = ["asm-keccak256","mixed-case-function","mixed-case-variable","pascal-case-struct","screaming-snake-case-const"]
ignore = ["test/**/*.sol","script/**/*.sol","src/interfaces/**/*.sol"]
additional_compiler_profiles = [
{ name = "test", via_ir = false, optimizer = false }
]
compilation_restrictions = [
{ paths = "test/**", via_ir = false, optimizer = false }
]
[profile.default.fuzz]
runs = 1000
max_test_rejects = 4294967295
[profile.pr.fuzz]
runs = 10000
max_test_rejects = 4294967295
[profile.ci.fuzz]
runs = 100000
max_test_rejects = 4294967295
[profile.debug]
via_ir = false
optimizer_runs = 200
fuzz.runs = 100
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
````
## File: LICENSE
````
Business Source License 1.1
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
"Business Source License" is a trademark of MariaDB Corporation Ab.
-----------------------------------------------------------------------------
Parameters
Licensor: GPRP
Licensed Work: Symbiotic Core
The Licensed Work is (c) 2024 GPRP
Additional Use Grant: None
Change Date: 2026-07-19
Change License: GNU General Public License v2.0 or later
-----------------------------------------------------------------------------
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.
MariaDB hereby grants you permission to use this License’s text to license
your works, and to refer to it using the trademark "Business Source License",
as long as you comply with the Covenants of Licensor below.
-----------------------------------------------------------------------------
Covenants of Licensor
In consideration of the right to use this License’s text and the "Business
Source License" name and trademark, Licensor covenants to MariaDB, and to all
other recipients of the licensed work to be provided by Licensor:
1. To specify as the Change License the GPL Version 2.0 or any later version,
or a license that is compatible with GPL Version 2.0 or a later version,
where "compatible" means that software provided under the Change License can
be included in a program with software provided under GPL Version 2.0 or a
later version. Licensor may specify additional Change Licenses without
limitation.
2. To either: (a) specify an additional grant of rights to use that does not
impose any additional restriction on the right granted in this License, as
the Additional Use Grant; or (b) insert the text "None".
3. To specify a Change Date.
4. Not to modify this License in any other way.
-----------------------------------------------------------------------------
Notice
The Business Source License (this document, or the "License") is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.
````
## File: package.json
````json
{
"name": "@symbioticfi/core",
"version": "1.0.3",
"description": "Symbiotic is a shared security protocol enabling decentralized networks to control and customize their own multi-asset restaking implementation.",
"homepage": "https://symbiotic.fi/",
"bugs": "https://github.com/symbioticfi/core/issues",
"license": "BUSL-1.1",
"author": "Symbiotic Team",
"files": [
"src/**/*",
"test/mocks/**/*",
"test/integration/**/*",
"script/**/*"
],
"repository": {
"type": "git",
"url": "https://github.com/symbioticfi/core.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security"
],
"dependencies": {
"@openzeppelin/contracts": "5.0.2",
"@openzeppelin/contracts-upgradeable": "5.0.2"
}
}
````
## File: README.md
````markdown
**[Symbiotic Protocol](https://symbiotic.fi) is an extremely flexible and permissionless shared security system.**
This repository contains the core Symbiotic smart contracts responsible for managing deposits, stake allocations and slashing.
[](https://deepwiki.com/symbioticfi/core)
Symbiotic core consists of:
- **Collateral**: a new type of asset that allows stakeholders to hold onto their funds and earn yield from them without needing to lock these funds in a direct manner or convert them to another type of asset.
- **Vaults**: the delegation and restaking management layer of Symbiotic that handles three crucial parts of the Symbiotic economy: accounting, delegation strategies, and reward distribution.
- **Operators**: entities running infrastructure for decentralized networks within and outside of the Symbiotic ecosystem.
- **Resolvers**: contracts or entities that are able to veto slashing incidents forwarded from networks and can be shared across networks.
- **Networks**: any protocols that require a decentralized infrastructure network to deliver a service in the crypto economy, e.g., enabling developers to launch decentralized applications by taking care of validating and ordering transactions, providing off-chain data to applications in the crypto economy, or providing users with guarantees about cross-network interactions, etc.
## Documentation
- [What is Symbiotic?](https://docs.symbiotic.fi/)
- [What is Collateral?](https://docs.symbiotic.fi/modules/collateral)
- [What is Vault?](https://docs.symbiotic.fi/category/vault)
## Usage
### Dependencies
- Git ([installation](https://git-scm.com/downloads))
- Foundry ([installation](https://getfoundry.sh/introduction/installation/))
### Prerequisites
**Clone the repository**
```
git clone --recurse-submodules https://github.com/symbioticfi/core.git
```
### Deploy Your Vault
- If you need a common (non-tokenized) Vault deployment
Open [`DeployVault.s.sol`](./script/DeployVault.s.sol), you will see config like this:
```solidity
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
address OWNER = 0x0000000000000000000000000000000000000000;
// Address of the collateral token
address COLLATERAL = 0x0000000000000000000000000000000000000000;
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
address BURNER = 0x000000000000000000000000000000000000dEaD;
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
uint48 EPOCH_DURATION = 7 days;
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
uint64 DELEGATOR_INDEX = 0;
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
address[] NETWORK_ALLOCATION_SETTERS_OR_NETWORK = [0x0000000000000000000000000000000000000000];
// Setting depending on the delegator type:
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
address[] OPERATOR_ALLOCATION_SETTERS_OR_OPERATOR = [0x0000000000000000000000000000000000000000];
// Whether to deploy a slasher
bool WITH_SLASHER = true;
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
uint64 SLASHER_INDEX = 1;
// Duration of a veto period (should be less than EPOCH_DURATION)
uint48 VETO_DURATION = 1 days;
// Optional
// Deposit limit (maximum amount of the active stake allowed in the vault)
uint256 DEPOSIT_LIMIT = 0;
// Addresses of the whitelisted depositors
address[] WHITELISTED_DEPOSITORS = new address[](0);
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
address HOOK = 0x0000000000000000000000000000000000000000;
// Delay in epochs for a network to update a resolver
uint48 RESOLVER_SET_EPOCHS_DELAY = 3;
```
Edit needed fields, and execute the script via:
```
forge script script/DeployVault.s.sol --rpc-url --private-key --broadcast
```
- If you need a tokenized (active deposits' shares are represented as ERC-20) Vault deployment
Open [`DeployVaultTokenized.s.sol`](./script/DeployVaultTokenized.s.sol), you will see config like this:
```solidity
// Name of the ERC20 representing shares of the active stake in the vault
string NAME = "SymVault";
// Symbol of the ERC20 representing shares of the active stake in the vault
string SYMBOL = "SV";
// Address of the owner of the vault who can migrate the vault to new versions whitelisted by Symbiotic
address OWNER = 0x0000000000000000000000000000000000000000;
// Address of the collateral token
address COLLATERAL = 0x0000000000000000000000000000000000000000;
// Vault's burner to send slashed funds to (e.g., 0xdEaD or some unwrapper contract; not used in case of no slasher)
address BURNER = 0x000000000000000000000000000000000000dEaD;
// Duration of the vault epoch (the withdrawal delay for staker varies from EPOCH_DURATION to 2 * EPOCH_DURATION depending on when the withdrawal is requested)
uint48 EPOCH_DURATION = 7 days;
// Type of the delegator:
// 0. NetworkRestakeDelegator (allows restaking across multiple networks and having multiple operators per network)
// 1. FullRestakeDelegator (do not use without knowing what you are doing)
// 2. OperatorSpecificDelegator (allows restaking across multiple networks with only a single operator)
// 3. OperatorNetworkSpecificDelegator (allocates the stake to a specific operator and network)
uint64 DELEGATOR_INDEX = 0;
// Setting depending on the delegator type:
// 0. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 1. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 2. NetworkLimitSetRoleHolders (adjust allocations for networks)
// 3. network (the only network that will receive the stake; should be an array with a single element)
address[] NETWORK_ALLOCATION_SETTERS_OR_NETWORK = [0x0000000000000000000000000000000000000000];
// Setting depending on the delegator type:
// 0. OperatorNetworkSharesSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 1. OperatorNetworkLimitSetRoleHolders (adjust allocations for operators inside networks; in shares, resulting percentage is operatorShares / totalOperatorShares)
// 2. operator (the only operator that will receive the stake; should be an array with a single element)
// 3. operator (the only operator that will receive the stake; should be an array with a single element)
address[] OPERATOR_ALLOCATION_SETTERS_OR_OPERATOR = [0x0000000000000000000000000000000000000000];
// Whether to deploy a slasher
bool WITH_SLASHER = true;
// Type of the slasher:
// 0. Slasher (allows instant slashing)
// 1. VetoSlasher (allows having a veto period if the resolver is set)
uint64 SLASHER_INDEX = 1;
// Duration of a veto period (should be less than EPOCH_DURATION)
uint48 VETO_DURATION = 1 days;
// Optional
// Deposit limit (maximum amount of the active stake allowed in the vault)
uint256 DEPOSIT_LIMIT = 0;
// Addresses of the whitelisted depositors
address[] WHITELISTED_DEPOSITORS = new address[](0);
// Address of the hook contract which, e.g., can automatically adjust the allocations on slashing events (not used in case of no slasher)
address HOOK = 0x0000000000000000000000000000000000000000;
// Delay in epochs for a network to update a resolver
uint48 RESOLVER_SET_EPOCHS_DELAY = 3;
```
Edit needed fields, and execute the script via:
```
forge script script/DeployVaultTokenized.s.sol --rpc-url --private-key --broadcast
```
In the console, you will see logs like these:
```bash
Deployed vault
vault:0x9c9e536A269ec83a0628404e35b2F940d7226c8C
delegator:0xb7a105A294f7E2d399C9692c12ba4cAba90F5AAB
slasher:0x8D2E18628F28660cF75Ca51C85a354d7c8508B59
```
### Interact with Vaults
There are 9 predefined [action-scripts](./script/actions/), that you can use from the start:
- [RegisterOperator](./script/actions/RegisterOperator.s.sol) – register an operator in the `OperatorRegistry`
- [OptInVault](./script/actions/OptInVault.s.sol) – opt-in operator to the vault
- [OptInNetwork](./script/actions/OptInNetwork.s.sol) – opt-in operator to the network
- [SetMaxNetworkLimit](./script/actions/SetMaxNetworkLimit.s.sol) – set new [maximum network limit](https://docs.symbiotic.fi/modules/registries/#3-network-to-vault-opt-in) for the vault
- [SetNetworkLimit](./script/actions/SetNetworkLimit.s.sol) – set a [network limit](https://docs.symbiotic.fi/modules/registries/#4-vault-to-network-opt-in) (how much stake the vault curator is ready to give to the subnetwork)
- [SetOperatorNetworkShares](./script/actions/SetOperatorNetworkShares.s.sol) – set an [operator's shares for a subnetwork](https://docs.symbiotic.fi/modules/registries/#5-vault-to-operators-opt-in) (what percentage, which is equal to the shares divided by the total operators' shares, of the subnetwork's stake the vault curator is ready to give to the operator)
- [SetHook](./script/actions/SetHook.s.sol) – configure [automation hooks](https://docs.symbiotic.fi/modules/extensions/hooks) that react to slashing events
- [SetResolver](./script/actions/SetResolver.s.sol) – set a new [resolver](https://docs.symbiotic.fi/modules/counterparties/resolvers) for the vault (only if the vault uses [VetoSlasher](https://docs.symbiotic.fi/modules/vault/slashing#1-vetoslasher))
- [VetoSlash](./script/actions/VetoSlash.s.sol) – [veto a pending slash request](https://docs.symbiotic.fi/modules/vault/slashing#1-vetoslasher) during the veto period
Interaction with different actions is similar; let's consider [SetNetworkLimit](./script/actions/SetNetworkLimit.s.sol) as an example:
1. Open [SetNetworkLimit.s.sol](./script/actions/SetNetworkLimit.s.sol), you will see config like this:
```solidity
// Address of the Vault
address constant VAULT = address(0);
// Address of the Network to set the network limit for
address constant NETWORK = address(0);
// Subnetwork Identifier
uint96 constant IDENTIFIER = 0;
// Network limit value to set
uint256 constant LIMIT = 0;
```
2. Edit needed fields, and execute the operation:
- If you use an EOA and want to execute the script:
```bash
forge script script/actions/SetNetworkLimit.s.sol --rpc-url --private-key --broadcast
```
- If you use a Safe multisig and want to get a transaction calldata:
```bash
forge script script/actions/SetMaxNetworkLimit.s.sol --rpc-url --sender --unlocked
```
In the logs, you will see `data` and `target` fields like this:
```bash
SetNetworkLimit data:
data:0x02145348759d4335cb712aa188935c2bd3aa6d205ac613050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
target:0xd6c4b4267BFB908BBdf8C9BDa7d0Ae517aA145b0
```
In Safe->TransactionBuilder, you should:
- enable "Custom data"
- enter `target` as a target address
- use the `data` (e.g., `0x02145348759d4335cb712aa188935c2bd3aa6d205ac61305...`) received earlier as a `Data (Hex encoded)`
Moreover, a [Tenderly](https://tenderly.co/) simulation link is provided as an additional safeguard, e.g.:
```bash
Simulation link:
https://dashboard.tenderly.co/TENDERLY_USERNAME/TENDERLY_PROJECT/simulator/new?network=1&contractAddress=0xd6c4b4267BFB908BBdf8C9BDa7d0Ae517aA145b0&from=0x2aCA71020De61bb532008049e1Bd41E451aE8AdC&rawFunctionInput=0x02145348759d4335cb712aa188935c2bd3aa6d205ac613050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
```
### Build, Test, and Format
```
forge build
forge test
forge fmt
```
**Configure environment**
Create `.env` based on the template:
```
ETH_RPC_URL=
ETHERSCAN_API_KEY=
```
## Security
Security audits are aggregated in `./audits`.
````
## File: remappings.txt
````
forge-std/=lib/forge-std/src/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@base/contracts=lib/contracts
````
---
## Rewards
This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).
# File Summary
## Purpose
This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
## File Format
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A header with the file path (## File: path/to/file)
b. The full contents of the file in a code block
## Usage Guidelines
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
## Notes
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching these patterns are excluded: docs/
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)
# Directory Structure
```
.github/
workflows/
lint.yml
test.yml
audits/
ChainSecurity-Rewards.pdf
OtterSec-Core&Rewards.pdf
Statemind-Core&Rewards.pdf
cli/
defaultOperatorRewards/
data/
distribution.json.example
trees.json.example
distributionToProofs.js
distributionToRoots.js
distributionToTrees.js
treesToDistribution.js
treesToProofs.js
treesToRoots.js
script/
deploy/
genesis/
DefaultOperatorRewardsFactory.s.sol
DefaultRewardsFactories.s.sol
DefaultStakerRewardsFactory.s.sol
DefaultOperatorRewards.s.sol
DefaultStakerRewards.s.sol
specs/
OperatorRewards.md
StakerRewards.md
src/
contracts/
defaultOperatorRewards/
DefaultOperatorRewards.sol
DefaultOperatorRewardsFactory.sol
defaultStakerRewards/
DefaultStakerRewards.sol
DefaultStakerRewardsFactory.sol
interfaces/
defaultOperatorRewards/
IDefaultOperatorRewards.sol
IDefaultOperatorRewardsFactory.sol
defaultStakerRewards/
IDefaultStakerRewards.sol
IDefaultStakerRewardsFactory.sol
stakerRewards/
IStakerRewards.sol
test/
defaultOperatorRewards/
DefaultOperatorRewards.t.sol
DefaultOperatorRewardsFactory.t.sol
defaultStakerRewards/
DefaultStakerRewards.t.sol
DefaultStakerRewardsFactory.t.sol
integration/
SymbioticRewardsBindings.sol
SymbioticRewardsConstants.sol
SymbioticRewardsImports.sol
SymbioticRewardsImportsContracts.sol
SymbioticRewardsInit.sol
SymbioticRewardsIntegration.sol
SymbioticRewardsIntegrationExample.sol
mocks/
SimpleStakerRewards.sol
stakerRewards/
StakerRewards.t.sol
.env.example
.gitignore
.gitmodules
foundry.toml
LICENSE
package.json
README.md
remappings.txt
```
# Files
## File: .github/workflows/lint.yml
````yaml
name: lint
on:
push:
branches:
- main
pull_request:
jobs:
run-linters:
name: Run linters
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v3
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Lint
run: forge fmt --check
````
## File: .github/workflows/test.yml
````yaml
name: test
on:
push:
branches:
- main
pull_request:
jobs:
run-tests:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Run Forge tests
run: |
forge test -vvv
id: test
````
## File: cli/defaultOperatorRewards/data/distribution.json.example
````
[
{
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"operators": [
{
"operator": "0x0000000000000000000000000000000000000001",
"reward": "100000000000000000"
},
{
"operator": "0x0000000000000000000000000000000000000002",
"reward": "300000000000000000"
},
{
"operator": "0x0000000000000000000000000000000000000003",
"reward": "600000000000000000"
}
]
},
{
"token": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"operators": [
{
"operator": "0x0000000000000000000000000000000000000002",
"reward": "200000000000000000"
},
{
"operator": "0x0000000000000000000000000000000000000003",
"reward": "250000000000000000"
},
{
"operator": "0x0000000000000000000000000000000000000004",
"reward": "500000000000000000"
}
]
}
]
````
## File: cli/defaultOperatorRewards/data/trees.json.example
````
[{"token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","tree":{"format":"standard-v1","leafEncoding":["address","uint256"],"tree":["0x1421466e8f910cab140a44dd533adb90ebc2d87e0ab91e851737a77ecd394224","0x54ce56851dece12f32823f4bb940800fb9cf57d68bcdda73e2436bf1e5be661d","0xb77d490dc0f9580cc767909bba59fd55900dec274b637ed820a391c018c8858a","0x92864efb389a13533b2b5d94eda464bce7dbe336d06c6d5feb673c30460c10ee","0x1c93c9b111fdf5d2ab331e2ad2de1d3ffe1c8590f544554a1b0247bd46be37a4"],"values":[{"value":["0x0000000000000000000000000000000000000001","100000000000000000"],"treeIndex":2},{"value":["0x0000000000000000000000000000000000000002","300000000000000000"],"treeIndex":3},{"value":["0x0000000000000000000000000000000000000003","600000000000000000"],"treeIndex":4}]}},{"token":"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0","tree":{"format":"standard-v1","leafEncoding":["address","uint256"],"tree":["0x4317f898d0c584ac608ed5c819f16cf5307fa2f07d5e1aa995493e46662a7a7f","0x30f6473979500545c8fa671ffec7060e0504909b4977e2a19af00c1c7c72fb49","0xc0151a5b2dc7e51c8ef30cdc65dfbedf3082c5678bad3ba3354827c6c6f52a45","0x5fa8fb18326605f1825c6988667a5162b2d926adb03d1cb670eddccf6a7ea42e","0x5c1aed882581724b9b52eecbc172dbc8f0ff57dde40b93f18139429763e0ccbd"],"values":[{"value":["0x0000000000000000000000000000000000000002","200000000000000000"],"treeIndex":3},{"value":["0x0000000000000000000000000000000000000003","250000000000000000"],"treeIndex":2},{"value":["0x0000000000000000000000000000000000000004","500000000000000000"],"treeIndex":4}]}}]
````
## File: cli/defaultOperatorRewards/distributionToProofs.js
````javascript
function generateMerkleTrees() {
⋮----
Distribution.forEach((tokenData) => {
const values = tokenData.operators.map(({ operator, reward }) => [
⋮----
reward.toString(),
⋮----
const tree = StandardMerkleTree.of(values, ['address', 'uint256'])
⋮----
function findProof(trees, operator) {
for (const [token, { tree, values }] of Object.entries(trees)) {
for (const [index, value] of values.entries()) {
if (value[0].toLowerCase() === operator.toLowerCase()) {
const proof = tree.getProof(index)
console.log(`-------------------------------`)
console.log(`Token: ${token}`)
console.log(`Proof: ${JSON.stringify(proof)}`)
⋮----
function main() {
const trees = generateMerkleTrees()
⋮----
console.error('Please provide an operator address.')
process.exit(1)
⋮----
findProof(trees, operator)
⋮----
main()
````
## File: cli/defaultOperatorRewards/distributionToRoots.js
````javascript
function generateMerkleTrees() {
⋮----
Distribution.forEach((tokenData) => {
const values = tokenData.operators.map(({ operator, reward }) => [
⋮----
reward.toString(),
⋮----
const tree = StandardMerkleTree.of(values, ['address', 'uint256'])
⋮----
function main() {
const trees = generateMerkleTrees()
⋮----
for (const [token, { tree }] of Object.entries(trees)) {
console.log(`-------------------------------`)
console.log(`Token: ${token}`)
console.log(`Merkle Root: ${tree.root}`)
⋮----
main()
````
## File: cli/defaultOperatorRewards/distributionToTrees.js
````javascript
function generateMerkleTrees() {
⋮----
Distribution.forEach((tokenData) => {
const values = tokenData.operators.map(({ operator, reward }) => [
⋮----
reward.toString(),
⋮----
const tree = StandardMerkleTree.of(values, ['address', 'uint256'])
⋮----
function main() {
const trees = generateMerkleTrees()
⋮----
for (const [token, { tree }] of Object.entries(trees)) {
treesJson.push({ token, tree })
⋮----
const filePath = path.join(__dirname, fileName)
⋮----
fs.writeFileSync(filePath, JSON.stringify(treesJson, null, 2))
console.log(`Trees written to ${fileName}`)
⋮----
main()
````
## File: cli/defaultOperatorRewards/treesToDistribution.js
````javascript
function parseMerkleTrees() {
⋮----
Trees.forEach((tokenData) => {
const values = tokenData.tree.values.map(
⋮----
const tree = StandardMerkleTree.of(values, ['address', 'uint256'])
⋮----
function main() {
const trees = parseMerkleTrees()
⋮----
for (const [token, { values }] of Object.entries(trees)) {
distributionJson.push({
⋮----
operators: values.map(([operator, reward]) => ({
⋮----
const filePath = path.join(__dirname, fileName)
⋮----
fs.writeFileSync(filePath, JSON.stringify(distributionJson, null, 2))
console.log(`Distribution written to ${fileName}`)
⋮----
main()
````
## File: cli/defaultOperatorRewards/treesToProofs.js
````javascript
function parseMerkleTrees() {
⋮----
Trees.forEach((tokenData) => {
const values = tokenData.tree.values.map(
⋮----
const tree = StandardMerkleTree.of(values, ['address', 'uint256'])
⋮----
function findProof(trees, operator) {
for (const [token, { tree, values }] of Object.entries(trees)) {
for (const [index, value] of values.entries()) {
if (value[0].toLowerCase() === operator.toLowerCase()) {
const proof = tree.getProof(index)
console.log(`-------------------------------`)
console.log(`Token: ${token}`)
console.log(`Proof: ${JSON.stringify(proof)}`)
⋮----
function main() {
const trees = parseMerkleTrees()
⋮----
console.error('Please provide an operator address.')
process.exit(1)
⋮----
findProof(trees, operator)
⋮----
main()
````
## File: cli/defaultOperatorRewards/treesToRoots.js
````javascript
function parseMerkleTrees() {
⋮----
Trees.forEach((tokenData) => {
const values = tokenData.tree.values.map(
⋮----
const tree = StandardMerkleTree.load(tokenData.tree);
⋮----
function main() {
const trees = parseMerkleTrees()
⋮----
for (const [token, { tree }] of Object.entries(trees)) {
console.log(`-------------------------------`)
console.log(`Token: ${token}`)
console.log(`Merkle Root: ${tree.root}`)
⋮----
main()
````
## File: script/deploy/genesis/DefaultOperatorRewardsFactory.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2, Script} from "forge-std/Script.sol";
⋮----
import {SymbioticCoreConstants} from "@symbioticfi/core/test/integration/SymbioticCoreConstants.sol";
⋮----
import {DefaultOperatorRewards} from "../../../src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol";
import {DefaultOperatorRewardsFactory} from
"../../../src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol";
⋮----
contract DefaultOperatorRewardsFactoryScript is Script {
function run() external {
````
## File: script/deploy/genesis/DefaultRewardsFactories.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2, Script} from "forge-std/Script.sol";
⋮----
import {SymbioticCoreConstants} from "@symbioticfi/core/test/integration/SymbioticCoreConstants.sol";
⋮----
import {DefaultStakerRewards} from "../../../src/contracts/defaultStakerRewards/DefaultStakerRewards.sol";
import {DefaultStakerRewardsFactory} from "../../../src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol";
⋮----
import {DefaultOperatorRewards} from "../../../src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol";
import {DefaultOperatorRewardsFactory} from
"../../../src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol";
⋮----
contract DefaultRewardsFactoriesScript is Script {
function run() external {
````
## File: script/deploy/genesis/DefaultStakerRewardsFactory.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2, Script} from "forge-std/Script.sol";
⋮----
import {SymbioticCoreConstants} from "@symbioticfi/core/test/integration/SymbioticCoreConstants.sol";
⋮----
import {DefaultStakerRewards} from "../../../src/contracts/defaultStakerRewards/DefaultStakerRewards.sol";
import {DefaultStakerRewardsFactory} from "../../../src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol";
⋮----
contract DefaultStakerRewardsFactoryScript is Script {
function run() external {
````
## File: script/deploy/DefaultOperatorRewards.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2, Script} from "forge-std/Script.sol";
⋮----
import {SymbioticRewardsConstants} from "../../test/integration/SymbioticRewardsConstants.sol";
⋮----
contract DefaultOperatorRewardsScript is Script {
function run() external {
````
## File: script/deploy/DefaultStakerRewards.s.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {console2, Script} from "forge-std/Script.sol";
⋮----
import {SymbioticRewardsConstants} from "../../test/integration/SymbioticRewardsConstants.sol";
⋮----
import {IDefaultStakerRewards} from "../../src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
⋮----
contract DefaultStakerRewardsScript is Script {
function run(
````
## File: specs/OperatorRewards.md
````markdown
## Operator Rewards
The network distributes the operator rewards at its discretion. Here are three examples:
1. The network performs off-chain calculations to determine the reward distributions. After calculating the rewards, the network executes batch transfers to distribute the rewards in a consolidated manner.
2. The network performs off-chain calculations to determine rewards and generates a Merkle tree, allowing operators to claim their rewards.
3. The network performs on-chain reward calculations within its middleware to determine the distribution of rewards.
##### Source of Data for Network On-Chain Reward Calculations
For operator rewards, the delegator module of the vault provides:
- `Delegator.stakeAt(network, operator, timestamp, hint)` - Active stake of an operator in the network.
Additionally, all operators register through the network, providing necessary details such as commission rates, fixed payments, and other relevant conditions. This registration process ensures that networks have the required data to perform accurate on-chain reward calculations in their middleware.
### Deploy
```shell
source .env
```
#### Deploy factory
Deployment script: [click](../script/deploy/genesis/DefaultOperatorRewardsFactory.s.sol)
```shell
forge script script/deploy/genesis/DefaultOperatorRewardsFactory.s.sol:DefaultOperatorRewardsFactoryScript --broadcast --rpc-url=$ETH_RPC_URL
```
#### Deploy entity
Deployment script: [click](../script/deploy/DefaultOperatorRewards.s.sol)
```shell
forge script script/deploy/DefaultOperatorRewards.s.sol:DefaultOperatorRewardsScript --sig "run()" --broadcast --rpc-url=$ETH_RPC_URL
```
### CLI
#### Install packages
```shell
npm install
```
#### Use commands
**distributionToRoots**
```shell
node cli/defaultOperatorRewards/distributionToRoots.js
```
Get a Merkle root for each rewards distribution by token.
_Make sure to save `distribution.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/distribution.json.example)._
---
**distributionToProofs**
```shell
node cli/defaultOperatorRewards/distributionToProofs.js OPERATOR
```
Get proofs for all tokens in a rewards distribution for a given operator.
_Make sure to save `distribution.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/distribution.json.example)._
Arguments:
- `OPERATOR` - an address of the operator to get proofs for
---
**distributionToTrees**
```shell
node cli/defaultOperatorRewards/distributionToTrees.js
```
Saves OZ Merkle tree structures constructed from the rewards distribution to `cli/defaultOperatorRewards/data/trees.json`.
_Make sure to save `distribution.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/distribution.json.example)._
---
**treesToRoots**
```shell
node cli/defaultOperatorRewards/treesToRoots.js
```
Get a Merkle root for each Merkle tree by token.
_Make sure to save `trees.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/trees.json.example)._
---
**treesToProofs**
```shell
node cli/defaultOperatorRewards/treesToProofs.js OPERATOR
```
Get proofs for all tokens in Merkle trees for a given operator.
_Make sure to save `trees.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/trees.json.example)._
Arguments:
- `OPERATOR` - an address of the operator to get proofs for
---
**treesToDistribution**
```shell
node cli/defaultOperatorRewards/treesToDistribution.js
```
Saves a rewards distribution constructed from the OZ Merkle trees to `cli/defaultOperatorRewards/data/distribution.json`.
_Make sure to save `trees.json` to `cli/defaultOperatorRewards/data` folder. You can check [an example format here](../cli/defaultOperatorRewards/data/trees.json.example)._
````
## File: specs/StakerRewards.md
````markdown
## Staker Rewards
For staker rewards calculation, the vault provides the following data:
- `activeSharesOfAt(account, timestamp, hint)` - $\text{active}$ shares of the user at a specific timestamp
- `activeSharesAt(timestamp, hint)` - total $\text{active}$ shares at a specific timestamp.
- Other checkpointed getters
Reward processing is not integrated into the vault's functionality. Instead, external reward contracts should manage this using the provided data.
However, we created the first version of the `IStakerRewards` interface to facilitate more generic reward distribution across networks.
- `IStakerRewards.version()` - provides a version of the interface that a particular rewards contract uses
- `IStakerRewards.distributeRewards(network, token, amount, data)` - call to distribute `amount` of `token` on behalf of `network` using an arbitrary `data`
### Deploy
```shell
source .env
```
#### Deploy factory
Deployment script: [click](../script/deploy/genesis/DefaultStakerRewardsFactory.s.sol)
```shell
forge script script/deploy/genesis/DefaultStakerRewardsFactory.s.sol:DefaultStakerRewardsFactoryScript --broadcast --rpc-url=$ETH_RPC_URL
```
#### Deploy entity
Deployment script: [click](../script/deploy/DefaultStakerRewards.s.sol)
```shell
forge script script/deploy/DefaultStakerRewards.s.sol:DefaultStakerRewardsScript 0x0000000000000000000000000000000000000000 0 0x0000000000000000000000000000000000000000 0x0000000000000000000000000000000000000000 0x0000000000000000000000000000000000000000 --sig "run(address,uint256,address,address,address)" --broadcast --rpc-url=$ETH_RPC_URL
```
````
## File: src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDefaultOperatorRewards} from "../../interfaces/defaultOperatorRewards/IDefaultOperatorRewards.sol";
⋮----
import {INetworkMiddlewareService} from "@symbioticfi/core/src/interfaces/service/INetworkMiddlewareService.sol";
⋮----
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract DefaultOperatorRewards is ReentrancyGuardUpgradeable, IDefaultOperatorRewards {
⋮----
/**
* @inheritdoc IDefaultOperatorRewards
*/
⋮----
function initialize() public initializer {
⋮----
function distributeRewards(address network, address token, uint256 amount, bytes32 root_) external nonReentrant {
⋮----
function claimRewards(
````
## File: src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {DefaultOperatorRewards} from "./DefaultOperatorRewards.sol";
⋮----
import {IDefaultOperatorRewardsFactory} from
"../../interfaces/defaultOperatorRewards/IDefaultOperatorRewardsFactory.sol";
⋮----
import {Registry} from "@symbioticfi/core/src/contracts/common/Registry.sol";
⋮----
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
⋮----
contract DefaultOperatorRewardsFactory is Registry, IDefaultOperatorRewardsFactory {
⋮----
/**
* @inheritdoc IDefaultOperatorRewardsFactory
*/
function create() external returns (address) {
````
## File: src/contracts/defaultStakerRewards/DefaultStakerRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDefaultStakerRewards} from "../../interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
import {IStakerRewards} from "../../interfaces/stakerRewards/IStakerRewards.sol";
⋮----
import {INetworkMiddlewareService} from "@symbioticfi/core/src/interfaces/service/INetworkMiddlewareService.sol";
import {IRegistry} from "@symbioticfi/core/src/interfaces/common/IRegistry.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
⋮----
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {MulticallUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract DefaultStakerRewards is
⋮----
/**
* @inheritdoc IStakerRewards
*/
⋮----
/**
* @inheritdoc IDefaultStakerRewards
*/
⋮----
function rewardsLength(address token, address network) external view returns (uint256) {
⋮----
function claimable(
⋮----
// network - a network to claim rewards for
// maxRewards - the maximum amount of rewards to process
⋮----
function initialize(
⋮----
function distributeRewards(
⋮----
// timestamp - a time point stakes must be taken into account at
// maxAdminFee - the maximum admin fee to allow
// activeSharesHint - a hint index to optimize `activeSharesAt()` processing
// activeStakeHint - a hint index to optimize `activeStakeAt()` processing
⋮----
function claimRewards(address recipient, address token, bytes calldata data) external override nonReentrant {
⋮----
// activeSharesOfHints - hint indexes to optimize `activeSharesOf()` processing
⋮----
function claimAdminFee(address recipient, address token) external nonReentrant onlyRole(ADMIN_FEE_CLAIM_ROLE) {
⋮----
function setAdminFee(
⋮----
function _setAdminFee(
````
## File: src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {DefaultStakerRewards} from "./DefaultStakerRewards.sol";
⋮----
import {IDefaultStakerRewardsFactory} from "../../interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol";
⋮----
import {Registry} from "@symbioticfi/core/src/contracts/common/Registry.sol";
⋮----
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
⋮----
contract DefaultStakerRewardsFactory is Registry, IDefaultStakerRewardsFactory {
⋮----
/**
* @inheritdoc IDefaultStakerRewardsFactory
*/
function create(
````
## File: src/interfaces/defaultOperatorRewards/IDefaultOperatorRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IDefaultOperatorRewards {
⋮----
/**
* @notice Emitted when rewards are distributed by a particular network using a given token by providing a Merkle root.
* @param network address of the network that distributed rewards
* @param token address of the token
* @param amount amount of tokens sent to the contract
* @param root Merkle root of the rewards distribution
* @dev The Merkle tree's leaves must represent an account and a claimable amount (the total amount of the reward tokens for the whole time).
*/
event DistributeRewards(address indexed network, address indexed token, uint256 amount, bytes32 root);
⋮----
/**
* @notice Emitted when rewards are claimed by a particular account for a particular network using a given token.
* @param recipient address of the rewards' recipient
* @param network address of the network
* @param token address of the token
* @param claimer address of the rewards' claimer
* @param amount amount of tokens claimed
*/
event ClaimRewards(
⋮----
/**
* @notice Get the network middleware service's address.
* @return address of the network middleware service
*/
function NETWORK_MIDDLEWARE_SERVICE() external view returns (address);
⋮----
/**
* @notice Get a Merkle root of a reward distribution for a particular network and token.
* @param network address of the network
* @param token address of the token
* @return Merkle root of the reward distribution
*/
function root(address network, address token) external view returns (bytes32);
⋮----
/**
* @notice Get an amount of tokens that can be claimed for a particular network.
* @param network address of the network
* @param token address of the token
* @return amount of tokens that can be claimed
*/
function balance(address network, address token) external view returns (uint256);
⋮----
/**
* @notice Get a claimed amount of rewards for a particular account, network, and token.
* @param network address of the network
* @param token address of the token
* @param account address of the claimer
* @return claimed amount of tokens
*/
function claimed(address network, address token, address account) external view returns (uint256);
⋮----
/**
* @notice Distribute rewards by a particular network using a given token by providing a Merkle root.
* @param network address of the network
* @param token address of the token
* @param amount amount of tokens to send to the contract
* @param root Merkle root of the reward distribution
*/
function distributeRewards(address network, address token, uint256 amount, bytes32 root) external;
⋮----
/**
* @notice Claim rewards for a particular network and token by providing a Merkle proof.
* @param recipient address of the rewards' recipient
* @param network address of the network
* @param token address of the token
* @param totalClaimable total amount of the reward tokens for the whole time
* @param proof Merkle proof of the reward distribution
* @return amount amount of tokens claimed
*/
function claimRewards(
````
## File: src/interfaces/defaultOperatorRewards/IDefaultOperatorRewardsFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IRegistry} from "@symbioticfi/core/src/interfaces/common/IRegistry.sol";
⋮----
interface IDefaultOperatorRewardsFactory is IRegistry {
/**
* @notice Create a default operator rewards contract.
* @return address of the created operator rewards contract
*/
function create() external returns (address);
````
## File: src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IStakerRewards} from "../stakerRewards/IStakerRewards.sol";
⋮----
interface IDefaultStakerRewards is IStakerRewards {
⋮----
/**
* @notice Initial parameters needed for a staker rewards contract deployment.
* @param vault address of the vault to get stakers' data from
* @param adminFee admin fee (up to ADMIN_FEE_BASE inclusively)
* @param defaultAdminRoleHolder address of the initial DEFAULT_ADMIN_ROLE holder
* @param adminFeeClaimRoleHolder address of the initial ADMIN_FEE_CLAIM_ROLE holder
* @param adminFeeSetRoleHolder address of the initial ADMIN_FEE_SET_ROLE holder
*/
⋮----
/**
* @notice Structure for a reward distribution.
* @param amount amount of tokens to be distributed (admin fee is excluded)
* @param timestamp time point stakes must taken into account at
*/
⋮----
/**
* @notice Emitted when a vault is initialized.
* @param vault address of the vault
*/
event InitVault(address vault);
⋮----
/**
* @notice Emitted when a reward is claimed.
* @param network network whose rewards are claimed
* @param token address of the token
* @param claimer address of the claimer
* @param firstClaimedRewardIndex first claimed reward index
* @param rewardsClaimed number of rewards claimed
*/
event ClaimRewardsExtra(
⋮----
/**
* @notice Emitted when an admin fee is claimed.
* @param recipient account that received the fee
* @param amount amount of the fee claimed
*/
event ClaimAdminFee(address indexed recipient, uint256 amount);
⋮----
/**
* @notice Emitted when the admin fee is set.
* @param adminFee new admin fee
*/
event SetAdminFee(uint256 adminFee);
⋮----
/**
* @notice Get the maximum admin fee (= 100%).
* @return maximum admin fee
*/
function ADMIN_FEE_BASE() external view returns (uint256);
⋮----
/**
* @notice Get the admin fee claimer's role.
* @return identifier of the admin fee claimer role
*/
function ADMIN_FEE_CLAIM_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get the admin fee setter's role.
* @return identifier of the admin fee setter role
*/
function ADMIN_FEE_SET_ROLE() external view returns (bytes32);
⋮----
/**
* @notice Get the vault factory's address.
* @return address of the vault factory
*/
function VAULT_FACTORY() external view returns (address);
⋮----
/**
* @notice Get the network middleware service's address.
* @return address of the network middleware service
*/
function NETWORK_MIDDLEWARE_SERVICE() external view returns (address);
⋮----
/**
* @notice Get the vault's address.
* @return address of the vault
*/
function VAULT() external view returns (address);
⋮----
/**
* @notice Get an admin fee.
* @return admin fee
*/
function adminFee() external view returns (uint256);
⋮----
/**
* @notice Get a total number of rewards using a particular token for a given network.
* @param token address of the token
* @param network address of the network
* @return total number of the rewards using the token by the network
*/
function rewardsLength(address token, address network) external view returns (uint256);
⋮----
/**
* @notice Get a particular reward distribution.
* @param token address of the token
* @param network address of the network
* @param rewardIndex index of the reward distribution using the token
* @return amount amount of tokens to be distributed
* @return timestamp time point stakes must taken into account at
*/
function rewards(
⋮----
/**
* @notice Get the first index of the unclaimed rewards using a particular token by a given account.
* @param account address of the account
* @param token address of the token
* @param network address of the network
* @return first index of the unclaimed rewards
*/
function lastUnclaimedReward(address account, address token, address network) external view returns (uint256);
⋮----
/**
* @notice Get a claimable admin fee amount for a particular token.
* @param token address of the token
* @return claimable admin fee
*/
function claimableAdminFee(
⋮----
/**
* @notice Claim an admin fee.
* @param recipient account that will receive the fee
* @param token address of the token
* @dev Only the vault owner can call this function.
*/
function claimAdminFee(address recipient, address token) external;
⋮----
/**
* @notice Set an admin fee.
* @param adminFee admin fee (up to ADMIN_FEE_BASE inclusively)
* @dev Only the ADMIN_FEE_SET_ROLE holder can call this function.
*/
function setAdminFee(
````
## File: src/interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDefaultStakerRewards} from "./IDefaultStakerRewards.sol";
⋮----
import {IRegistry} from "@symbioticfi/core/src/interfaces/common/IRegistry.sol";
⋮----
interface IDefaultStakerRewardsFactory is IRegistry {
/**
* @notice Create a default staker rewards contract for a given vault.
* @param params initial parameters needed for a staker rewards contract deployment
* @return address of the created staker rewards contract
*/
function create(
````
## File: src/interfaces/stakerRewards/IStakerRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IStakerRewards {
/**
* @notice Emitted when a reward is distributed.
* @param network network on behalf of which the reward is distributed
* @param token address of the token
* @param distributeAmount amount of tokens to distribute
* @param adminFeeAmount amount of tokens to keep as an admin fee
* @param timestamp timestamp of the distribution
*/
event DistributeRewards(
⋮----
/**
* @notice Emitted when a reward is claimed.
* @param network network whose rewards are claimed
* @param token address of the token
* @param claimer address of the claimer
* @param amount amount of tokens
* @param recipient address of the tokens' recipient
*/
event ClaimRewards(
⋮----
/**
* @notice Get a version of the staker rewards contract (different versions mean different interfaces).
* @return version of the staker rewards contract
* @dev Must return 2 for this one.
*/
function version() external view returns (uint64);
⋮----
/**
* @notice Get an amount of rewards claimable by a particular account of a given token.
* @param token address of the token
* @param account address of the claimer
* @param data some data to use
* @return amount of claimable tokens
*/
function claimable(address token, address account, bytes calldata data) external view returns (uint256);
⋮----
/**
* @notice Distribute rewards on behalf of a particular network using a given token.
* @param network network on behalf of which the reward to distribute
* @param token address of the token
* @param amount amount of tokens
* @param data some data to use
*/
function distributeRewards(address network, address token, uint256 amount, bytes calldata data) external;
⋮----
/**
* @notice Claim rewards using a given token.
* @param recipient address of the tokens' recipient
* @param token address of the token
* @param data some data to use
*/
function claimRewards(address recipient, address token, bytes calldata data) external;
````
## File: test/defaultOperatorRewards/DefaultOperatorRewards.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
import {Token} from "@symbioticfi/core/test/mocks/Token.sol";
⋮----
import {DefaultOperatorRewardsFactory} from
"../../src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol";
import {DefaultOperatorRewards} from "../../src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol";
import {IDefaultOperatorRewards} from "../../src/interfaces/defaultOperatorRewards/IDefaultOperatorRewards.sol";
⋮----
import {FeeOnTransferToken} from "@symbioticfi/core/test/mocks/FeeOnTransferToken.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
⋮----
contract DefaultOperatorRewardsTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_DitributeRewards(
⋮----
function test_DitributeRewardsFeeOnTransfer(
⋮----
function test_DitributeRewardsFeeOnTransferRevertInsufficientTransfer() public {
⋮----
function test_DitributeRewardsRevertNotNetworkMiddleware(
⋮----
function test_ClaimRewards(uint256 amount1, uint256 amount2) public {
⋮----
function test_ClaimRewardsRevertRootNotSet(
⋮----
function test_ClaimRewardsRevertInvalidProof(
⋮----
function test_ClaimRewardsRevertInsufficientTotalClaimable(
⋮----
function test_ClaimRewardsRevertInsufficientBalance(
⋮----
function test_ClaimRewardsCustom() public {
⋮----
function _getOperatorDefaultRewards() internal returns (IDefaultOperatorRewards) {
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _distributeRewards(address user, address network, address token, uint256 amount, bytes32 root) internal {
⋮----
function _claimRewards(
````
## File: test/defaultOperatorRewards/DefaultOperatorRewardsFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
⋮----
import {DefaultOperatorRewardsFactory} from
"../../src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol";
import {DefaultOperatorRewards} from "../../src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol";
import {IDefaultOperatorRewards} from "../../src/interfaces/defaultOperatorRewards/IDefaultOperatorRewards.sol";
⋮----
contract DefaultOperatorRewardsFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/defaultStakerRewards/DefaultStakerRewards.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "@symbioticfi/core/src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "@symbioticfi/core/src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "@symbioticfi/core/src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "@symbioticfi/core/src/contracts/OperatorRegistry.sol";
import {MetadataService} from "@symbioticfi/core/src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "@symbioticfi/core/src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from
"@symbioticfi/core/src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "@symbioticfi/core/src/contracts/slasher/VetoSlasher.sol";
⋮----
import {Token} from "@symbioticfi/core/test/mocks/Token.sol";
import {VaultConfigurator, IVaultConfigurator} from "@symbioticfi/core/src/contracts/VaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
⋮----
import {DefaultStakerRewardsFactory} from "../../src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol";
import {IDefaultStakerRewards} from "../../src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
⋮----
import {DefaultStakerRewards} from "../../src/contracts/defaultStakerRewards/DefaultStakerRewards.sol";
⋮----
import {FeeOnTransferToken} from "@symbioticfi/core/test/mocks/FeeOnTransferToken.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {VaultHints} from "@symbioticfi/core/src/contracts/hints/VaultHints.sol";
⋮----
contract DefaultStakerRewardsTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_CreateRevertMissingRoles1(uint256 adminFee, address adminFeeSetRoleHolder) public {
⋮----
function test_CreateRevertMissingRoles2(
⋮----
function test_CreateRevertMissingRoles3(
⋮----
function test_CreateRevertInvalidAdminFee(
⋮----
function test_ReinitRevert() public {
⋮----
function test_DistributeRewards(
⋮----
function test_DistributeRewardsHints(
⋮----
function test_DistributeRewardsRevertNotNetworkMiddleware(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_DistributeRewardsRevertInvalidRewardTimestamp1(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_DistributeRewardsRevertInvalidRewardTimestamp2(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_DistributeRewardsRevertHighAdminFee(
⋮----
function test_DistributeRewardsRevertInsufficientReward(
⋮----
function test_ClaimRewards(uint256 amount, uint256 ditributeAmount1, uint256 ditributeAmount2) public {
⋮----
function test_ClaimRewardsBoth(uint256 amount, uint256 ditributeAmount1, uint256 ditributeAmount2) public {
⋮----
function test_ClaimRewardsManyWithoutHints(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimRewardsManyWithHints(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimRewardsRevertInvalidRecipient(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimRewardsRevertNoRewardsToClaim1(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimRewardsRevertNoRewardsToClaim2(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimRewardsRevertInvalidHintsLength(uint256 amount, uint256 ditributeAmount) public {
⋮----
function test_ClaimAdminFee(uint256 amount, uint256 ditributeAmount, uint256 adminFee) public {
⋮----
function test_ClaimAdminFeeRevertInsufficientAdminFee(
⋮----
function test_SetAdminFee(
⋮----
function test_SetAdminFeeRevertAlreadySet(
⋮----
function _getStakerDefaultRewards() internal returns (DefaultStakerRewards) {
⋮----
function _registerOperator(
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
⋮----
function _grantAdminFeeSetRole(address user, address account) internal {
⋮----
function _distributeRewards(
⋮----
function _claimRewards(
⋮----
function _setAdminFee(address user, uint256 adminFee) internal {
⋮----
function _claimAdminFee(address user, address token) internal {
````
## File: test/defaultStakerRewards/DefaultStakerRewardsFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "@symbioticfi/core/src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "@symbioticfi/core/src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "@symbioticfi/core/src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "@symbioticfi/core/src/contracts/OperatorRegistry.sol";
import {MetadataService} from "@symbioticfi/core/src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "@symbioticfi/core/src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {OperatorNetworkSpecificDelegator} from
"@symbioticfi/core/src/contracts/delegator/OperatorNetworkSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "@symbioticfi/core/src/contracts/slasher/VetoSlasher.sol";
⋮----
import {Token} from "@symbioticfi/core/test/mocks/Token.sol";
import {VaultConfigurator, IVaultConfigurator} from "@symbioticfi/core/src/contracts/VaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
⋮----
import {DefaultStakerRewardsFactory} from "../../src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol";
import {DefaultStakerRewards} from "../../src/contracts/defaultStakerRewards/DefaultStakerRewards.sol";
import {IDefaultStakerRewards} from "../../src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
⋮----
contract DefaultStakerRewardsFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(
⋮----
function test_CreateRevertNotVault() public {
⋮----
function _registerOperator(
⋮----
function _registerNetwork(address user, address middleware) internal {
⋮----
function _deposit(address user, uint256 amount) internal returns (uint256 depositedAmount, uint256 mintedShares) {
⋮----
function _withdraw(address user, uint256 amount) internal returns (uint256 burnedShares, uint256 mintedShares) {
````
## File: test/integration/SymbioticRewardsBindings.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticRewardsImports.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
contract SymbioticRewardsBindings is Test {
⋮----
function _createDefaultStakerRewards_SymbioticRewards(
⋮----
function _createDefaultOperatorRewards_SymbioticRewards(
⋮----
function _distributeRewards_SymbioticRewards(
⋮----
function _claimRewards_SymbioticRewards(
⋮----
function _claimAdminFee_SymbioticRewards(
⋮----
function _setAdminFee_SymbioticRewards(
⋮----
function _grantRole_SymbioticRewards(address who, address where, bytes32 role, address account) internal virtual {
⋮----
function _grantRoleDefaultAdmin_SymbioticRewards(address who, address where, address account) internal virtual {
⋮----
function _grantRoleAdminFeeClaim_SymbioticRewards(address who, address where, address account) internal virtual {
⋮----
function _grantRoleAdminFeeSet_SymbioticRewards(address who, address where, address account) internal virtual {
````
## File: test/integration/SymbioticRewardsConstants.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticRewardsImports.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
function defaultStakerRewardsFactory() internal view returns (ISymbioticDefaultStakerRewardsFactory) {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
⋮----
// hoodi
⋮----
function defaultOperatorRewardsFactory() internal view returns (ISymbioticDefaultOperatorRewardsFactory) {
````
## File: test/integration/SymbioticRewardsImports.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {
IDefaultStakerRewards as ISymbioticDefaultStakerRewards,
IStakerRewards as ISymbioticStakerRewards
} from "../../src/interfaces/defaultStakerRewards/IDefaultStakerRewards.sol";
import {IDefaultStakerRewardsFactory as ISymbioticDefaultStakerRewardsFactory} from
"../../src/interfaces/defaultStakerRewards/IDefaultStakerRewardsFactory.sol";
import {IDefaultOperatorRewards as ISymbioticDefaultOperatorRewards} from
"../../src/interfaces/defaultOperatorRewards/IDefaultOperatorRewards.sol";
import {IDefaultOperatorRewardsFactory as ISymbioticDefaultOperatorRewardsFactory} from
"../../src/interfaces/defaultOperatorRewards/IDefaultOperatorRewardsFactory.sol";
⋮----
interface SymbioticRewardsImports {}
````
## File: test/integration/SymbioticRewardsImportsContracts.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {DefaultStakerRewards as SymbioticDefaultStakerRewards} from
"../../src/contracts/defaultStakerRewards/DefaultStakerRewards.sol";
import {DefaultStakerRewardsFactory as SymbioticDefaultStakerRewardsFactory} from
"../../src/contracts/defaultStakerRewards/DefaultStakerRewardsFactory.sol";
import {DefaultOperatorRewards as SymbioticDefaultOperatorRewards} from
"../../src/contracts/defaultOperatorRewards/DefaultOperatorRewards.sol";
import {DefaultOperatorRewardsFactory as SymbioticDefaultOperatorRewardsFactory} from
"../../src/contracts/defaultOperatorRewards/DefaultOperatorRewardsFactory.sol";
⋮----
interface SymbioticRewardsImportsContracts {}
````
## File: test/integration/SymbioticRewardsInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreInit.sol";
⋮----
import "./SymbioticRewardsImports.sol";
⋮----
import {SymbioticRewardsConstants} from "./SymbioticRewardsConstants.sol";
import {SymbioticRewardsBindings} from "./SymbioticRewardsBindings.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract SymbioticRewardsInit is SymbioticCoreInit, SymbioticRewardsBindings {
⋮----
// General config
⋮----
// Middleware-related config
⋮----
// DefaultStakerRewards-related config
⋮----
function setUp() public virtual override {
⋮----
// ------------------------------------------------------------ GENERAL HELPERS ------------------------------------------------------------ //
⋮----
function _initRewards_SymbioticRewards() internal virtual {
⋮----
function _initRewards_SymbioticRewards(
⋮----
// ------------------------------------------------------------ REWARDS-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getDefaultStakerRewards_SymbioticRewards(
⋮----
function _getDefaultStakerRewardsRandom_SymbioticRewards(
⋮----
function _getDefaultOperatorRewards_SymbioticRewards() internal virtual returns (address) {
⋮----
function _getDefaultOperatorRewardsRandom_SymbioticRewards() internal virtual returns (address) {
⋮----
function _fundMiddleware_SymbioticRewards(address token, address middleware) internal virtual {
deal(token, middleware, _normalizeForToken_Symbiotic(SYMBIOTIC_REWARDS_TOKENS_TO_SET_TIMES_1e18, token), true); // should cover most cases
⋮----
// ------------------------------------------------------------ STAKER-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _stakerClaim_SymbioticRewards(
⋮----
function _stakerClaimWeak_SymbioticRewards(
⋮----
// ------------------------------------------------------------ OPERATOR-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _operatorClaim_SymbioticRewards(
⋮----
// ------------------------------------------------------------ CURATOR-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _curatorClaim_SymbioticRewards(
⋮----
function _curatorClaimWeak_SymbioticRewards(
⋮----
function _curatorSetAdminFee_SymbioticRewards(
````
## File: test/integration/SymbioticRewardsIntegration.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreIntegration.sol";
⋮----
import "./SymbioticRewardsInit.sol";
⋮----
contract SymbioticRewardsIntegration is SymbioticRewardsInit, SymbioticCoreIntegration {
⋮----
uint256 public SYMBIOTIC_REWARDS_DISTRIBUTE_STAKER_REWARDS_CHANCE = 4; // lower -> higher probability
⋮----
function setUp() public virtual override(SymbioticRewardsInit, SymbioticCoreIntegration) {
⋮----
function _loadExistingEntities_SymbioticRewards() internal virtual {
⋮----
function _loadExistingDefaultStakerRewards_SymbioticRewards() internal virtual {
⋮----
function _loadExistingDefaultOperatorRewards_SymbioticRewards() internal virtual {
⋮----
function _addPossibleTokens_SymbioticRewards() internal virtual {
⋮----
function _addExistingEntities_SymbioticRewards() internal virtual {
⋮----
function _addExistingDefaultStakerRewards_SymbioticRewards() internal virtual {
⋮----
function _addExistingDefaultOperatorRewards_SymbioticRewards() internal virtual {
⋮----
function _createEnvironment_SymbioticRewards() internal virtual {
⋮----
function _createParties_SymbioticRewards() internal virtual {
⋮----
function _createDefaultStakerRewards_SymbioticRewards() internal virtual {
⋮----
function _createDefaultOperatorRewards_SymbioticRewards() internal virtual {
⋮----
function _distributeRewards_SymbioticRewards() internal virtual {
⋮----
function _distributeStakerRewardsOnBehalfOfNetworkRandom_SymbioticRewards(
⋮----
function _distributeStakerRewards_SymbioticRewards() internal virtual {
⋮----
function _distributeOperatorRewards_SymbioticRewards() internal virtual {}
⋮----
function _claimRewards_SymbioticRewards() internal virtual {
⋮----
function _claimStakerRewards_SymbioticRewards() internal virtual {
⋮----
function _claimOperatorRewards_SymbioticRewards() internal virtual {}
````
## File: test/integration/SymbioticRewardsIntegrationExample.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticRewardsIntegration.sol";
⋮----
import {console2} from "forge-std/Test.sol";
⋮----
contract SymbioticRewardsIntegrationExample is SymbioticRewardsIntegration {
⋮----
uint256 public SELECT_OPERATOR_CHANCE = 1; // lower -> higher probability
⋮----
function setUp() public override {
⋮----
// vm.selectFork(vm.createFork(vm.rpcUrl("holesky")));
// SYMBIOTIC_INIT_BLOCK = 2_727_202;
// SYMBIOTIC_CORE_USE_EXISTING_DEPLOYMENT = true;
// SYMBIOTIC_REWARDS_USE_EXISTING_DEPLOYMENT = true;
⋮----
function test_NetworkDistributeRewardsForStake() public {
````
## File: test/mocks/SimpleStakerRewards.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IStakerRewards} from "../../src/interfaces/stakerRewards/IStakerRewards.sol";
⋮----
contract SimpleStakerRewards is IStakerRewards {
/**
* @inheritdoc IStakerRewards
*/
⋮----
function claimable(address token, address account, bytes memory data) external view override returns (uint256) {}
⋮----
function distributeRewards(address network, address token, uint256 amount, bytes memory data) external override {
⋮----
function claimRewards(address recipient, address token, bytes memory data) external override {}
````
## File: test/stakerRewards/StakerRewards.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
⋮----
import {SimpleStakerRewards} from "test/mocks/SimpleStakerRewards.sol";
⋮----
contract StakerRewardsTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: .env.example
````
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
````
## File: .gitignore
````
# Compiler files
cache/
out/**/
!out/DefaultStakerRewardsFactory.sol/
!out/DefaultStakerRewards.sol/
!out/DefaultOperatorRewardsFactory.sol/
!out/DefaultOperatorRewards.sol/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/*/11155111/
/broadcast/**/dry-run/
# Docs
docs/
# Dotenv file
.env
# Other files
.gas-snapshot
lcov.info
node_modules
package-lock.json
````
## File: .gitmodules
````
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/core"]
path = lib/core
url = https://github.com/symbioticfi/core
````
## File: foundry.toml
````toml
[profile.default]
evm_version = "cancun"
solc = "0.8.25"
optimizer = true
optimizer_runs = 200
via_ir = true
src = "src"
out = "out"
libs = ["lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
gas_reports = ["*"]
gas_limit = "18446744073709551615"
[rpc_endpoints]
mainnet = "${ETH_RPC_URL}"
holesky = "${ETH_RPC_URL_HOLESKY}"
[fmt]
bracket_spacing = false
int_types = "long"
line_length = 120
multiline_func_header = "params_first"
number_underscore = "thousands"
quote_style = "double"
tab_width = 4
[fuzz]
runs = 4096
max_test_rejects = 262144
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
````
## File: LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: package.json
````json
{
"name": "@symbioticfi/rewards",
"version": "2.0.0",
"description": "Symbiotic Rewards repository contains a Symbiotic Staker Rewards interface providing a standardized way for rewards implementations by different parties, and default implementations of Staker and Operator Rewards.",
"homepage": "https://symbiotic.fi/",
"bugs": "https://github.com/symbioticfi/rewards/issues",
"license": "MIT",
"author": "Symbiotic Team",
"files": [
"src/**/*",
"test/mocks/**/*",
"test/integration/**/*",
"out/**/*.json",
"cli/**/*"
],
"repository": {
"type": "git",
"url": "https://github.com/symbioticfi/rewards.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security"
],
"dependencies": {
"@openzeppelin/contracts": "5.0.2",
"@openzeppelin/contracts-upgradeable": "5.0.2",
"@openzeppelin/merkle-tree": "1.0.7",
"@symbioticfi/core": "1.0.1"
}
}
````
## File: README.md
````markdown
**[Symbiotic Protocol](https://symbiotic.fi) is an extremely flexible and permissionless shared security system.**
This repository contains a Symbiotic Staker Rewards interface, its default implementation, and a default Operator Rewards.
[](https://deepwiki.com/symbioticfi/rewards)
## Documentation
Can be found [here](https://docs.symbiotic.fi/core-modules/rewards).
## Technical Documentation
Can be found [here](./specs).
## Security
Security audits can be found [here](./audits).
## Usage
### Env
Create `.env` file using a template:
```
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
```
\* ETH_RPC_URL is optional. \* ETH_RPC_URL_HOLESKY is optional. \* ETHERSCAN_API_KEY is optional.
### Build
```shell
forge build
```
### Test
```shell
forge test
```
### Format
```shell
forge fmt
```
### Gas Snapshots
```shell
forge snapshot
```
````
## File: remappings.txt
````
forge-std/=lib/forge-std/src/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@symbioticfi/core/=lib/core/
````
---
## Burners
This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).
# File Summary
## Purpose
This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
## File Format
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A header with the file path (## File: path/to/file)
b. The full contents of the file in a code block
## Usage Guidelines
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
## Notes
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching these patterns are excluded: docs/
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)
# Directory Structure
```
.github/
workflows/
lint.yml
test.yml
audits/
ChainSecurity-Burners.pdf
script/
deploy/
genesis/
BurnerRouterFactory.s.sol
Burners.s.sol
ETHx_Burner.s.sol
mETH_Burner.s.sol
rETH_Burner.s.sol
sfrxETH_Burner.s.sol
swETH_Burner.s.sol
wstETH_Burner.s.sol
BurnerRouter.s.sol
specs/
BurnerRouter.md
Burners.md
src/
contracts/
burners/
sUSDe/
sUSDe_Burner.sol
sUSDe_Miniburner.sol
ETHx_Burner.sol
mETH_Burner.sol
rETH_Burner.sol
sfrxETH_Burner.sol
swETH_Burner.sol
wstETH_Burner.sol
common/
AddressRequests.sol
SelfDestruct.sol
UintRequests.sol
router/
BurnerRouter.sol
BurnerRouterFactory.sol
interfaces/
burners/
ETHx/
IETHx_Burner.sol
IStaderConfig.sol
IStaderStakePoolsManager.sol
IUserWithdrawalManager.sol
mETH/
ImETH_Burner.sol
IMETH.sol
IStaking.sol
rETH/
IrETH_Burner.sol
IRocketTokenRETH.sol
sfrxETH/
IFraxEtherRedemptionQueue.sol
IsfrxETH_Burner.sol
sUSDe/
IEthenaMinting.sol
IsUSDe_Burner.sol
ISUSDe.sol
IUSDe.sol
swETH/
IswETH_Burner.sol
ISwETH.sol
ISwEXIT.sol
wstETH/
IWithdrawalQueue.sol
IwstETH_Burner.sol
IWstETH.sol
common/
IAddressRequests.sol
IUintRequests.sol
router/
IBurnerRouter.sol
IBurnerRouterFactory.sol
test/
burners/
ETHx_Burner.t.sol
mETH_Burner.t.sol
rETH_Burner.t.sol
sfrxETH_Burner.t.sol
sUSDe_Burner.t.sol
swETH_Burner.t.sol
wstETH_Burner.t.sol
common/
SelfDestruct.t.sol
integration/
SymbioticBurnersBindings.sol
SymbioticBurnersConstants.sol
SymbioticBurnersImports.sol
SymbioticBurnersImportsContracts.sol
SymbioticBurnersInit.sol
SymbioticBurnersIntegration.sol
SymbioticBurnersIntegrationExample.sol
router/
BurnerRouter.t.sol
BurnerRouterFactory.t.sol
.env.example
.gitignore
.gitmodules
foundry.toml
LICENSE
package.json
README.md
remappings.txt
```
# Files
## File: .github/workflows/lint.yml
````yaml
name: lint
on:
push:
branches:
- main
pull_request:
jobs:
run-linters:
name: Run linters
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v3
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Lint
run: forge fmt --check
````
## File: .github/workflows/test.yml
````yaml
name: test
on:
push:
branches:
- main
pull_request:
jobs:
run-tests:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Run Forge tests
run: |
forge test -vvv
id: test
env:
ETH_RPC_URL: ${{ secrets.ETH_RPC_URL }}
````
## File: script/deploy/genesis/BurnerRouterFactory.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {BurnerRouterFactory} from "../../../src/contracts/router/BurnerRouterFactory.sol";
import {BurnerRouter} from "../../../src/contracts/router/BurnerRouter.sol";
⋮----
contract BurnerRouterFactoryScript is Script {
function run() public {
````
## File: script/deploy/genesis/Burners.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {BurnerRouterFactory} from "../../../src/contracts/router/BurnerRouterFactory.sol";
import {BurnerRouter} from "../../../src/contracts/router/BurnerRouter.sol";
⋮----
import {wstETH_Burner} from "../../../src/contracts/burners/wstETH_Burner.sol";
import {rETH_Burner} from "../../../src/contracts/burners/rETH_Burner.sol";
import {mETH_Burner} from "../../../src/contracts/burners/mETH_Burner.sol";
import {swETH_Burner} from "../../../src/contracts/burners/swETH_Burner.sol";
import {sfrxETH_Burner} from "../../../src/contracts/burners/sfrxETH_Burner.sol";
import {ETHx_Burner} from "../../../src/contracts/burners/ETHx_Burner.sol";
⋮----
contract BurnersScript is Script {
function run() public {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
⋮----
// hoodi
````
## File: script/deploy/genesis/ETHx_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {ETHx_Burner} from "../../../src/contracts/burners/ETHx_Burner.sol";
⋮----
contract ETHx_BurnerScript is Script {
function run() public {
⋮----
// mainnet
⋮----
// holesky
````
## File: script/deploy/genesis/mETH_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {mETH_Burner} from "../../../src/contracts/burners/mETH_Burner.sol";
⋮----
contract mETH_BurnerScript is Script {
function run() public {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
````
## File: script/deploy/genesis/rETH_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {rETH_Burner} from "../../../src/contracts/burners/rETH_Burner.sol";
⋮----
contract rETH_BurnerScript is Script {
function run() public {
⋮----
// mainnet
⋮----
// holesky
````
## File: script/deploy/genesis/sfrxETH_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {sfrxETH_Burner} from "../../../src/contracts/burners/sfrxETH_Burner.sol";
⋮----
contract sfrxETH_BurnerScript is Script {
function run() public {
⋮----
// mainnet
````
## File: script/deploy/genesis/swETH_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {swETH_Burner} from "../../../src/contracts/burners/swETH_Burner.sol";
⋮----
contract swETH_BurnerScript is Script {
function run() public {
⋮----
// mainnet
````
## File: script/deploy/genesis/wstETH_Burner.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {wstETH_Burner} from "../../../src/contracts/burners/wstETH_Burner.sol";
⋮----
contract wstETH_BurnerScript is Script {
function run() public {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
````
## File: script/deploy/BurnerRouter.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {SymbioticBurnersConstants} from "../../test/integration/SymbioticBurnersConstants.sol";
⋮----
import {IBurnerRouter} from "../../src/interfaces/router/IBurnerRouter.sol";
⋮----
contract BurnerRouterScript is Script {
function run(
````
## File: specs/BurnerRouter.md
````markdown
## Burner Router
[See the code here](../src/contracts/router/)
The Burner Router allows redirecting the slashed collateral tokens to different addresses, which may be represented by Burners, Treasury contracts, LP lockers, etc.
### Full Flow
1. Setup
- Before the Vault's creation, deploy a new Burner Router via `BurnerRouterFactory` with the same collateral address as the Vault will use
- Deploy the Vault inputting the received `BurnerRouter` address and `IBaseSlasher.BaseParams.isBurnerHook` set to `true`
2. Update setup
- Change global receiver, network-specific receivers, operator-network-specific receivers with the configured delay (in case of pending set requests, they are overrided with the new ones)
- Change `delay` itself after the delay (in case of pending set requests, they are overrided with the new ones)
3. Slashing
- The router is called via `onSlash()` function
- It determines the needed address for redirection and saves the redirection amount for it
4. Trigger transfer
- Transfers a given account's whole balance from the router to this account
### Deploy
```shell
source .env
```
#### Deploy factory
Deployment script: [click](../script/deploy/genesis/BurnerRouterFactory.s.sol)
```shell
forge script script/deploy/genesis/BurnerRouterFactory.s.sol:BurnerRouterFactoryScript --broadcast --rpc-url=$ETH_RPC_URL
```
#### Deploy entity
Deployment script: [click](../script/deploy/BurnerRouter.s.sol)
```shell
forge script script/deploy/BurnerRouter.s.sol:BurnerRouterScript 0x0000000000000000000000000000000000000000 0x0000000000000000000000000000000000000000 0 0x0000000000000000000000000000000000000000 [\(0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000\),\(0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000\)] [\(0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000\),\(0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000\)] --sig "run(address,address,uint48,address,(address,address)[],(address,address,address)[])" --broadcast --rpc-url=$ETH_RPC_URL
```
````
## File: specs/Burners.md
````markdown
## Burners
## General Overview
Collateral is a concept introduced by Symbiotic that brings capital efficiency and scale by enabling assets used to secure Symbiotic networks to be held outside of the Symbiotic protocol itself - e.g., in DeFi positions on networks other than Ethereum itself.
Symbiotic achieves this by separating the ability to slash assets from the underlying asset itself, similar to how liquid staking tokens create tokenized representations of underlying staked positions. Technically, collateral positions in Symbiotic are ERC-20 tokens with extended functionality to handle slashing incidents if applicable. In other words, if the collateral token aims to support slashing, it should be possible to create a `Burner` responsible for proper burning of the asset.
For example, if asset is ETH LST it can be used as a collateral if it's possible to create `Burner` contract that withdraw ETH from beaconchain and burn it, if asset is native e.g. governance token it also can be used as collateral since burner might be implemented as "black-hole" contract or address.
## Default Burners
We've implemented default Burners for the assets restaked at Symbiotic, which need "unwrapping" (and allow it in a permissionless way):
### wstETH Burner
An asset transfered to the [Burner](../src/contracts/burners/wstETH_Burner.sol) - wstETH
#### Unwrap flow
1. Trigger withdrawal
- Unwrap wstETH into stETH via wstETH contract
- Create requests with acceptable by the Lido Withdrawal Queue amounts
- Send withdrawal requests to the Lido Withdrawal Queue
2. Trigger burn
- Claim withdrawal request by its ID
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/wstETH_Burner.s.sol)
```shell
forge script script/deploy/genesis/wstETH_Burner.s.sol:wstETH_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
### rETH Burner
An asset transfered to the [Burner](../src/contracts/burners/rETH_Burner.sol) - rETH
#### Unwrap flow
1. Trigger burn
- Unwrap rETH into ETH via rETH contract
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/rETH_Burner.s.sol)
```shell
forge script script/deploy/genesis/rETH_Burner.s.sol:rETH_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
### mETH Burner
An asset transfered to the [Burner](../src/contracts/burners/mETH_Burner.sol) - mETH
#### Unwrap flow
1. Trigger withdrawal
- Send a withdrawal request to the Mantle Staking contract
2. Trigger burn
- Claim withdrawal request by its ID
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/mETH_Burner.s.sol)
```shell
forge script script/deploy/genesis/mETH_Burner.s.sol:mETH_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
### swETH Burner
An asset transfered to the [Burner](../src/contracts/burners/swETH_Burner.sol) - swETH
#### Unwrap flow
1. Trigger withdrawal
- Create requests with acceptable by the Swell Exit contract amounts
- Send withdrawal requests to the Swell Exit contract
2. Trigger burn
- Claim withdrawal request by its ID
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/swETH_Burner.s.sol)
```shell
forge script script/deploy/genesis/swETH_Burner.s.sol:swETH_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
### sfrxETH Burner
An asset transfered to the [Burner](../src/contracts/burners/sfrxETH_Burner.sol) - sfrxETH
#### Unwrap flow
1. Trigger withdrawal
- Send a withdrawal request to the frxETH Redemption Queue
2. Trigger burn
- Claim withdrawal request by its ID
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/sfrxETH_Burner.s.sol)
```shell
forge script script/deploy/genesis/sfrxETH_Burner.s.sol:sfrxETH_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
### ETHx Burner
An asset transfered to the [Burner](../src/contracts/burners/ETHx_Burner.sol) - ETHx
#### Unwrap flow
1. Trigger withdrawal
- Create requests with acceptable by the User Withdraw Manager contract amounts
- Send withdrawal requests to the User Withdraw Manager contract
2. Trigger burn
- Claim withdrawal request by its ID
- Burn ETH by `selfdestruct()`
#### Deploy entity
Deployment script: [click](../script/deploy/genesis/ETHx_Burner.s.sol)
```shell
forge script script/deploy/genesis/ETHx_Burner.s.sol:ETHx_BurnerScript --broadcast --rpc-url=$ETH_RPC_URL
```
````
## File: src/contracts/burners/sUSDe/sUSDe_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {AddressRequests} from "../../common/AddressRequests.sol";
import {SelfDestruct} from "../../common/SelfDestruct.sol";
import {sUSDe_Miniburner} from "./sUSDe_Miniburner.sol";
⋮----
import {IEthenaMinting} from "../../../interfaces/burners/sUSDe/IEthenaMinting.sol";
import {ISUSDe} from "../../../interfaces/burners/sUSDe/ISUSDe.sol";
import {IUSDe} from "../../../interfaces/burners/sUSDe/IUSDe.sol";
import {IsUSDe_Burner} from "../../../interfaces/burners/sUSDe/IsUSDe_Burner.sol";
⋮----
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract sUSDe_Burner is AddressRequests, IERC1271, IsUSDe_Burner {
⋮----
/**
* @inheritdoc IsUSDe_Burner
*/
⋮----
/**
* @inheritdoc IERC1271
*/
function isValidSignature(bytes32 hash_, bytes memory signature) external view returns (bytes4) {
⋮----
function triggerWithdrawal() external returns (address requestId) {
⋮----
function triggerClaim(
⋮----
function triggerInstantClaim() external {
⋮----
function triggerBurn(
⋮----
function approveUSDeMinter() external {
````
## File: src/contracts/burners/sUSDe/sUSDe_Miniburner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {ISUSDe} from "../../../interfaces/burners/sUSDe/ISUSDe.sol";
⋮----
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
⋮----
contract sUSDe_Miniburner is OwnableUpgradeable {
⋮----
function initialize(
⋮----
function triggerClaim() external onlyOwner {
````
## File: src/contracts/burners/ETHx_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
import {UintRequests} from "../common/UintRequests.sol";
⋮----
import {IETHx_Burner} from "../../interfaces/burners/ETHx/IETHx_Burner.sol";
import {IStaderConfig} from "../../interfaces/burners/ETHx/IStaderConfig.sol";
import {IStaderStakePoolsManager} from "../../interfaces/burners/ETHx/IStaderStakePoolsManager.sol";
import {IUserWithdrawalManager} from "../../interfaces/burners/ETHx/IUserWithdrawalManager.sol";
⋮----
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {Multicall} from "@openzeppelin/contracts/utils/Multicall.sol";
⋮----
contract ETHx_Burner is UintRequests, Multicall, IETHx_Burner {
⋮----
/**
* @inheritdoc IETHx_Burner
*/
⋮----
function triggerWithdrawal(
⋮----
function triggerBurn(
````
## File: src/contracts/burners/mETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
import {UintRequests} from "../common/UintRequests.sol";
⋮----
import {IMETH} from "../../interfaces/burners/mETH/IMETH.sol";
import {IStaking} from "../../interfaces/burners/mETH/IStaking.sol";
import {ImETH_Burner} from "../../interfaces/burners/mETH/ImETH_Burner.sol";
⋮----
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract mETH_Burner is UintRequests, ImETH_Burner {
/**
* @inheritdoc ImETH_Burner
*/
⋮----
function triggerWithdrawal() external returns (uint256 requestId) {
⋮----
function triggerBurn(
````
## File: src/contracts/burners/rETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
⋮----
import {IRocketTokenRETH} from "../../interfaces/burners/rETH/IRocketTokenRETH.sol";
import {IrETH_Burner} from "../../interfaces/burners/rETH/IrETH_Burner.sol";
⋮----
contract rETH_Burner is IrETH_Burner {
/**
* @inheritdoc IrETH_Burner
*/
⋮----
function triggerBurn(
````
## File: src/contracts/burners/sfrxETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
import {UintRequests} from "../common/UintRequests.sol";
⋮----
import {IFraxEtherRedemptionQueue} from "../../interfaces/burners/sfrxETH/IFraxEtherRedemptionQueue.sol";
import {IsfrxETH_Burner} from "../../interfaces/burners/sfrxETH/IsfrxETH_Burner.sol";
⋮----
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
⋮----
contract sfrxETH_Burner is UintRequests, IsfrxETH_Burner, IERC721Receiver {
/**
* @inheritdoc IsfrxETH_Burner
*/
⋮----
function triggerWithdrawal() external returns (uint256 requestId) {
⋮----
function triggerBurn(
⋮----
/**
* @inheritdoc IERC721Receiver
*/
function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4) {
````
## File: src/contracts/burners/swETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
import {UintRequests} from "../common/UintRequests.sol";
⋮----
import {ISwEXIT} from "../../interfaces/burners/swETH/ISwEXIT.sol";
import {IswETH_Burner} from "../../interfaces/burners/swETH/IswETH_Burner.sol";
⋮----
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract swETH_Burner is UintRequests, IswETH_Burner, IERC721Receiver {
⋮----
/**
* @inheritdoc IswETH_Burner
*/
⋮----
function triggerWithdrawal(
⋮----
function triggerBurn(
⋮----
/**
* @inheritdoc IERC721Receiver
*/
function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4) {
````
## File: src/contracts/burners/wstETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {SelfDestruct} from "../common/SelfDestruct.sol";
import {UintRequests} from "../common/UintRequests.sol";
⋮----
import {IWithdrawalQueue} from "../../interfaces/burners/wstETH/IWithdrawalQueue.sol";
import {IWstETH} from "../../interfaces/burners/wstETH/IWstETH.sol";
import {IwstETH_Burner} from "../../interfaces/burners/wstETH/IwstETH_Burner.sol";
⋮----
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract wstETH_Burner is UintRequests, IwstETH_Burner {
⋮----
/**
* @inheritdoc IwstETH_Burner
*/
⋮----
function triggerWithdrawal(
⋮----
function triggerBurn(
⋮----
function triggerBurnBatch(uint256[] calldata requestIds_, uint256[] calldata hints) external {
````
## File: src/contracts/common/AddressRequests.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IAddressRequests} from "../../interfaces/common/IAddressRequests.sol";
⋮----
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract AddressRequests is IAddressRequests {
⋮----
/**
* @inheritdoc IAddressRequests
*/
function requestIdsLength() external view returns (uint256) {
⋮----
function requestIds(uint256 index, uint256 maxRequestIds) external view returns (address[] memory requestIds_) {
⋮----
function _addRequestId(
⋮----
function _removeRequestId(
````
## File: src/contracts/common/SelfDestruct.sol
````
// SPDX-License-Identifier: MIT
⋮----
contract SelfDestruct {
````
## File: src/contracts/common/UintRequests.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../interfaces/common/IUintRequests.sol";
⋮----
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract UintRequests is IUintRequests {
⋮----
/**
* @inheritdoc IUintRequests
*/
function requestIdsLength() external view returns (uint256) {
⋮----
function requestIds(uint256 index, uint256 maxRequestIds) external view returns (uint256[] memory requestIds_) {
⋮----
function _addRequestId(
⋮----
function _removeRequestId(
````
## File: src/contracts/router/BurnerRouter.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBurnerRouter} from "../../interfaces/router/IBurnerRouter.sol";
⋮----
import {IBurner} from "@symbioticfi/core/src/interfaces/slasher/IBurner.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract BurnerRouter is OwnableUpgradeable, IBurnerRouter {
⋮----
/**
* @inheritdoc IBurnerRouter
*/
⋮----
/**
* @inheritdoc IBurner
*/
function onSlash(
⋮----
uint256, /* amount */
uint48 /* captureTimestamp */
⋮----
function triggerTransfer(
⋮----
function setGlobalReceiver(
⋮----
function acceptGlobalReceiver() external {
⋮----
function setNetworkReceiver(address network, address receiver) external onlyOwner {
⋮----
function acceptNetworkReceiver(
⋮----
function setOperatorNetworkReceiver(address network, address operator, address receiver) external onlyOwner {
⋮----
function acceptOperatorNetworkReceiver(address network, address operator) external {
⋮----
function setDelay(
⋮----
function acceptDelay() external {
⋮----
function initialize(
⋮----
function _getReceiver(address network, address operator) internal view returns (address receiver) {
⋮----
function _setReceiver(
⋮----
function _acceptReceiver(Address storage currentReceiver, PendingAddress storage pendingReceiver) internal {
⋮----
function _tryAcceptDelay() internal {
````
## File: src/contracts/router/BurnerRouterFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {BurnerRouter} from "./BurnerRouter.sol";
⋮----
import {IBurnerRouterFactory} from "../../interfaces/router/IBurnerRouterFactory.sol";
⋮----
import {Registry} from "@symbioticfi/core/src/contracts/common/Registry.sol";
⋮----
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
⋮----
contract BurnerRouterFactory is Registry, IBurnerRouterFactory {
⋮----
/**
* @inheritdoc IBurnerRouterFactory
*/
function create(
````
## File: src/interfaces/burners/ETHx/IETHx_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../common/IUintRequests.sol";
⋮----
interface IETHx_Burner is IUintRequests {
⋮----
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param requestId request ID that was created
*/
event TriggerWithdrawal(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed and burned
*/
event TriggerBurn(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the Stader Config contract.
*/
function STADER_CONFIG() external view returns (address);
⋮----
/**
* @notice Get an address of the User Withdraw Manager contract.
*/
function USER_WITHDRAW_MANAGER() external view returns (address);
⋮----
/**
* @notice Get an address of the Stake Pools Manager contract.
*/
function STAKE_POOLS_MANAGER() external view returns (address);
⋮----
/**
* @notice Trigger a withdrawal of ETH from the collateral's underlying asset.
* @param maxWithdrawalAmount maximum amount of ETHx it is possible to withdraw in one request
* @return requestId request ID that was created
*/
function triggerWithdrawal(
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param requestId request ID of the withdrawal to process
*/
function triggerBurn(
````
## File: src/interfaces/burners/ETHx/IStaderConfig.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IStaderConfig {
function getUserWithdrawManager() external view returns (address);
⋮----
function getStakePoolManager() external view returns (address);
⋮----
function getMinWithdrawAmount() external view returns (uint256);
⋮----
function getMaxWithdrawAmount() external view returns (uint256);
⋮----
function getMinBlockDelayToFinalizeWithdrawRequest() external view returns (uint256);
````
## File: src/interfaces/burners/ETHx/IStaderStakePoolsManager.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IStaderStakePoolsManager {
// returns the amount of share corresponding to `_assets` assets
function previewDeposit(
⋮----
// return the amount of assets corresponding to `_shares` shares
function previewWithdraw(
````
## File: src/interfaces/burners/ETHx/IUserWithdrawalManager.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IUserWithdrawalManager {
function nextRequestId() external view returns (uint256);
⋮----
function nextRequestIdToFinalize() external view returns (uint256);
⋮----
/**
* @notice put a withdrawal request
* @param _ethXAmount amount of ethX shares to withdraw
* @param _owner owner of withdraw request to redeem
* @return requestId
*/
function requestWithdraw(uint256 _ethXAmount, address _owner) external returns (uint256);
⋮----
/**
* @notice finalize user requests
* @dev check for safeMode to finalizeRequest
*/
function finalizeUserWithdrawalRequest() external;
⋮----
/**
* @notice transfer the eth of finalized request to recipient and delete the request
* @param _requestId request id to redeem
*/
function claim(
````
## File: src/interfaces/burners/mETH/ImETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../common/IUintRequests.sol";
⋮----
interface ImETH_Burner is IUintRequests {
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param requestId request ID that was created
*/
event TriggerWithdrawal(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed and burned
*/
event TriggerBurn(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the Mantle Staking contract.
*/
function STAKING() external view returns (address);
⋮----
/**
* @notice Trigger a withdrawal of ETH from the collateral's underlying asset.
* @return requestId request ID that was created
*/
function triggerWithdrawal() external returns (uint256 requestId);
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param requestId request ID of the withdrawal to process
*/
function triggerBurn(
````
## File: src/interfaces/burners/mETH/IMETH.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IMETH {
/// @notice The staking contract which has permissions to mint tokens.
function stakingContract() external view returns (address);
⋮----
/// @notice Mint mETH to the staker.
/// @param staker The address of the staker.
/// @param amount The amount of tokens to mint.
/// @dev Expected to be called during the stake operation.
function mint(address staker, uint256 amount) external;
````
## File: src/interfaces/burners/mETH/IStaking.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IStaking {
/// @notice The minimum amount of mETH users can unstake.
function minimumUnstakeBound() external view returns (uint256);
⋮----
/// @notice Converts from ETH to mETH using the current exchange rate.
/// The exchange rate is given by the total supply of mETH and total ETH controlled by the protocol.
function mETHToETH(
⋮----
/// @notice Interface for users to submit a request to unstake.
/// @dev Transfers the specified amount of mETH to the staking contract and locks it there until it is burned on
/// request claim. The staking contract must therefore be approved to move the user's mETH on their behalf.
/// @param methAmount The amount of mETH to unstake.
/// @param minETHAmount The minimum amount of ETH that the user expects to receive.
/// @return The request ID.
function unstakeRequest(uint128 methAmount, uint128 minETHAmount) external returns (uint256);
⋮----
/// @notice Interface for users to claim their finalized and filled unstaking requests.
/// @dev See also {UnstakeRequestsManager} for a more detailed explanation of finalization and request filling.
function claimUnstakeRequest(
````
## File: src/interfaces/burners/rETH/IrETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IrETH_Burner {
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param assetAmount amount of collateral that was withdrawn
* @param ethAmount amount of ETH that was burned
*/
event TriggerBurn(address indexed caller, uint256 assetAmount, uint256 ethAmount);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param amount amount of collateral to burn
*/
function triggerBurn(
````
## File: src/interfaces/burners/rETH/IRocketTokenRETH.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IRocketTokenRETH {
// Calculate the amount of ETH backing an amount of rETH
function getEthValue(
⋮----
// Calculate the amount of rETH backed by an amount of ETH
function getRethValue(
⋮----
// Get the total amount of collateral available
// Includes rETH contract balance & excess deposit pool balance
function getTotalCollateral() external view returns (uint256);
⋮----
// Mint rETH
// Only accepts calls from the RocketDepositPool contract
function mint(uint256 _ethAmount, address _to) external;
⋮----
// Burn rETH for ETH
function burn(
````
## File: src/interfaces/burners/sfrxETH/IFraxEtherRedemptionQueue.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IFraxEtherRedemptionQueue {
/// @notice State of Frax's frxETH redemption queue
/// @return nextNftId Autoincrement for the NFT id
/// @return queueLengthSecs Current wait time (in seconds) a new redeemer would have. Should be close to Beacon.
/// @return redemptionFee Redemption fee given as a percentage with 1e6 precision
/// @return earlyExitFee Early NFT back to frxETH exit fee given as a percentage with 1e6 precision
function redemptionQueueState()
⋮----
/// @notice Enter the queue for redeeming sfrxEth to frxETH at the current rate, then frxETH to ETH 1-to-1. Must have approved or permitted first.
/// @notice Will generate a FrxETHRedemptionTicket NFT that can be redeemed for the actual ETH later.
/// @param _recipient Recipient of the NFT. Must be ERC721 compatible if a contract
/// @param _sfrxEthAmount Amount of sfrxETH to redeem (in shares / balanceOf)
/// @param _nftId The ID of the FrxEthRedemptionTicket NFT
/// @dev Must call approve/permit on frxEth contract prior to this call
function enterRedemptionQueueViaSfrxEth(
⋮----
/// @notice Redeems a FrxETHRedemptionTicket NFT for ETH. Must have reached the maturity date first.
/// @param _nftId The ID of the NFT
/// @param _recipient The recipient of the redeemed ETH
function burnRedemptionTicketNft(uint256 _nftId, address payable _recipient) external;
````
## File: src/interfaces/burners/sfrxETH/IsfrxETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../common/IUintRequests.sol";
⋮----
interface IsfrxETH_Burner is IUintRequests {
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param requestId request ID that was created
*/
event TriggerWithdrawal(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed and burned
*/
event TriggerBurn(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the Frax Ether Redemption Queue.
*/
function FRAX_ETHER_REDEMPTION_QUEUE() external view returns (address);
⋮----
/**
* @notice Trigger a withdrawal of ETH from the collateral's underlying asset.
* @return requestId request ID that was created
*/
function triggerWithdrawal() external returns (uint256 requestId);
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param requestId request ID of the withdrawal to process
*/
function triggerBurn(
````
## File: src/interfaces/burners/sUSDe/IEthenaMinting.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IEthenaMinting {
⋮----
/// @notice tracks asset type (STABLE or ASSET)
⋮----
/// @notice tracks if the asset is active
⋮----
/// @notice max mint per block this given asset
⋮----
/// @notice max redeem per block this given asset
⋮----
/// @notice USDe minted per block / per asset per block
⋮----
/// @notice USDe redeemed per block / per asset per block
⋮----
/// @notice max USDe that can be minted across all assets within a single block.
⋮----
/// @notice max USDe that can be redeemed across all assets within a single block.
⋮----
/// @notice hash an Order struct
function hashOrder(
⋮----
/// @notice total USDe that can be minted/redeemed across all assets per single block.
function totalPerBlockPerAsset(uint256 blockNumber, address asset) external view returns (BlockTotals memory);
⋮----
function totalPerBlock(
⋮----
/// @notice global single block totals
function globalConfig() external view returns (GlobalConfig memory);
⋮----
function tokenConfig(
⋮----
/// @notice Adds a benefactor address to the benefactor whitelist
function addWhitelistedBenefactor(
⋮----
/**
* @notice Redeem stablecoins for assets
* @param order struct containing order details and confirmation from server
* @param signature signature of the taker
*/
function redeem(Order calldata order, Signature calldata signature) external;
````
## File: src/interfaces/burners/sUSDe/IsUSDe_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IAddressRequests} from "../../common/IAddressRequests.sol";
⋮----
interface IsUSDe_Burner is IAddressRequests {
⋮----
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param amount amount of the collateral to be withdrawn
* @param requestId request ID that was created
*/
event TriggerWithdrawal(address indexed caller, uint256 amount, address requestId);
⋮----
/**
* @notice Emitted when a claim is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed
*/
event TriggerClaim(address indexed caller, address requestId);
⋮----
/**
* @notice Emitted when an instant claim is triggered.
* @param caller caller of the function
* @param amount amount of the collateral that was unwrapped
*/
event TriggerInstantClaim(address indexed caller, uint256 amount);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param asset address of the asset burned (except sUSDe and USDe)
* @param amount amount of the asset burned
*/
event TriggerBurn(address indexed caller, address indexed asset, uint256 amount);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the USDe contract.
*/
function USDE() external view returns (address);
⋮----
/**
* @notice Trigger a withdrawal of USDe from the collateral's underlying asset.
* @return requestId request ID that was created
*/
function triggerWithdrawal() external returns (address requestId);
⋮----
/**
* @notice Trigger a claim of USDe (if `cooldownDuration` didn't equal zero while triggering withdrawal).
* @param requestId request ID of the withdrawal to process
*/
function triggerClaim(
⋮----
/**
* @notice Trigger an instant claim of USDe (if `cooldownDuration` equals zero).
*/
function triggerInstantClaim() external;
⋮----
/**
* @notice Trigger a burn of any asset lying on this contract except sUSDe and USDe (after USDe redemption).
* @param asset address of the asset to burn
*/
function triggerBurn(
⋮----
/**
* @notice Approve the USDe to a minter (if a new minter appears).
*/
function approveUSDeMinter() external;
````
## File: src/interfaces/burners/sUSDe/ISUSDe.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface ISUSDe {
/**
* @dev See {IERC4626-asset}.
*/
function asset() external view returns (address);
⋮----
function cooldownDuration() external view returns (uint24);
⋮----
/// @notice redeem shares into assets and starts a cooldown to claim the converted underlying asset
/// @param shares shares to redeem
function cooldownShares(
⋮----
/**
* @dev See {IERC4626-previewRedeem}.
*/
function previewRedeem(
⋮----
/// @notice Set cooldown duration. If cooldown duration is set to zero, the StakedUSDeV2 behavior changes to follow ERC4626 standard and disables cooldownShares and cooldownAssets methods. If cooldown duration is greater than zero, the ERC4626 withdrawal and redeem functions are disabled, breaking the ERC4626 standard, and enabling the cooldownShares and the cooldownAssets functions.
/// @param duration Duration of the cooldown
function setCooldownDuration(
⋮----
/**
* @dev See {IERC4626-deposit}.
*/
function deposit(uint256 assets, address receiver) external returns (uint256);
⋮----
/**
* @dev See {IERC4626-redeem}.
*/
function redeem(uint256 shares, address receiver, address _owner) external returns (uint256);
⋮----
/// @notice Claim the staking amount after the cooldown has finished. The address can only retire the full amount of assets.
/// @dev unstake can be called after cooldown have been set to 0, to let accounts to be able to claim remaining assets locked at Silo
/// @param receiver Address to send the assets by the staker
function unstake(
````
## File: src/interfaces/burners/sUSDe/IUSDe.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IUSDe {
function minter() external view returns (address);
⋮----
function mint(address account, uint256 amount) external;
⋮----
/**
* @dev Destroys a `value` amount of tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(
````
## File: src/interfaces/burners/swETH/IswETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../common/IUintRequests.sol";
⋮----
interface IswETH_Burner is IUintRequests {
⋮----
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param firstRequestId first request ID that was created
* @param lastRequestId last request ID that was created
*/
event TriggerWithdrawal(address indexed caller, uint256 firstRequestId, uint256 lastRequestId);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed and burned
*/
event TriggerBurn(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the Swell Exit contract.
*/
function SWEXIT() external view returns (address);
⋮----
/**
* @notice Trigger a withdrawal of ETH from the collateral's underlying asset.
* @param maxRequests maximum number of withdrawal requests to create
* @return firstRequestId first request ID that was created
* @return lastRequestId last request ID that was created
*/
function triggerWithdrawal(
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param requestId request ID of the withdrawal to process
*/
function triggerBurn(
````
## File: src/interfaces/burners/swETH/ISwETH.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface ISwETH {
function deposit() external payable;
````
## File: src/interfaces/burners/swETH/ISwEXIT.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface ISwEXIT {
function getLastTokenIdCreated() external view returns (uint256);
⋮----
function withdrawRequestMaximum() external view returns (uint256);
⋮----
function withdrawRequestMinimum() external view returns (uint256);
⋮----
function processWithdrawals(
⋮----
function createWithdrawRequest(
⋮----
function finalizeWithdrawal(
````
## File: src/interfaces/burners/wstETH/IWithdrawalQueue.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IWithdrawalQueue {
/// @notice Lido stETH token address
function STETH() external view returns (address);
⋮----
/// @notice minimal amount of stETH that is possible to withdraw
function MIN_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
⋮----
/// @notice maximum amount of stETH that is possible to withdraw by a single request
/// Prevents accumulating too much funds per single request fulfillment in the future.
/// @dev To withdraw larger amounts, it's recommended to split it to several requests
function MAX_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
⋮----
/// @notice id of the last request
/// NB! requests are indexed from 1, so it returns 0 if there is no requests in the queue
function getLastRequestId() external view returns (uint256);
⋮----
/// @notice Request the batch of stETH for withdrawal. Approvals for the passed amounts should be done before.
/// @param _amounts an array of stETH amount values.
/// The standalone withdrawal request will be created for each item in the passed list.
/// @param _owner address that will be able to manage the created requests.
/// If `address(0)` is passed, `msg.sender` will be used as owner.
/// @return requestIds an array of the created withdrawal request ids
function requestWithdrawals(
⋮----
/// @notice Claim a batch of withdrawal requests if they are finalized sending locked ether to the owner
/// @param _requestIds array of request ids to claim
/// @param _hints checkpoint hint for each id. Can be obtained with `findCheckpointHints()`
/// @dev
/// Reverts if requestIds and hints arrays length differs
/// Reverts if any requestId or hint in arguments are not valid
/// Reverts if any request is not finalized or already claimed
/// Reverts if msg sender is not an owner of the requests
function claimWithdrawals(uint256[] calldata _requestIds, uint256[] calldata _hints) external;
⋮----
/// @notice Claim one`_requestId` request once finalized sending locked ether to the owner
/// @param _requestId request id to claim
/// @dev use unbounded loop to find a hint, which can lead to OOG
⋮----
/// Reverts if requestId or hint are not valid
/// Reverts if request is not finalized or already claimed
/// Reverts if msg sender is not an owner of request
function claimWithdrawal(
⋮----
/// @notice Finalize requests from last finalized one up to `_lastRequestIdToBeFinalized`
/// @dev ether to finalize all the requests should be calculated using `prefinalize()` and sent along
function finalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable;
⋮----
/// @notice length of the checkpoint array. Last possible value for the hint.
/// NB! checkpoints are indexed from 1, so it returns 0 if there is no checkpoints
function getLastCheckpointIndex() external view returns (uint256);
⋮----
/// @notice Finds the list of hints for the given `_requestIds` searching among the checkpoints with indices
/// in the range `[_firstIndex, _lastIndex]`.
/// NB! Array of request ids should be sorted
/// NB! `_firstIndex` should be greater than 0, because checkpoint list is 1-based array
/// Usage: findCheckpointHints(_requestIds, 1, getLastCheckpointIndex())
/// @param _requestIds ids of the requests sorted in the ascending order to get hints for
/// @param _firstIndex left boundary of the search range. Should be greater than 0
/// @param _lastIndex right boundary of the search range. Should be less than or equal to getLastCheckpointIndex()
/// @return hintIds array of hints used to find required checkpoint for the request
function findCheckpointHints(
````
## File: src/interfaces/burners/wstETH/IwstETH_Burner.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IUintRequests} from "../../common/IUintRequests.sol";
⋮----
interface IwstETH_Burner is IUintRequests {
⋮----
/**
* @notice Emitted when a withdrawal is triggered.
* @param caller caller of the function
* @param requestIds request IDs that were created
*/
event TriggerWithdrawal(address indexed caller, uint256[] requestIds);
⋮----
/**
* @notice Emitted when a burn is triggered.
* @param caller caller of the function
* @param requestId request ID of the withdrawal that was claimed and burned
*/
event TriggerBurn(address indexed caller, uint256 requestId);
⋮----
/**
* @notice Emitted when a batch burn is triggered.
* @param caller caller of the function
* @param requestIds request IDs of the withdrawals that were claimed and burned
*/
event TriggerBurnBatch(address indexed caller, uint256[] requestIds);
⋮----
/**
* @notice Get an address of the collateral.
*/
function COLLATERAL() external view returns (address);
⋮----
/**
* @notice Get an address of the stETH token.
*/
function STETH() external view returns (address);
⋮----
/**
* @notice Get an address of the Lido Withdrawal Queue.
*/
function LIDO_WITHDRAWAL_QUEUE() external view returns (address);
⋮----
/**
* @notice Get a minimum amount of stETH that can be withdrawn at a request.
*/
function MIN_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
⋮----
/**
* @notice Get a maximum amount of stETH that can be withdrawn at a request.
*/
function MAX_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
⋮----
/**
* @notice Trigger a withdrawal of ETH from the collateral's underlying asset.
* @param maxRequests maximum number of withdrawal requests to create
* @return requestIds request IDs that were created
*/
function triggerWithdrawal(
⋮----
/**
* @notice Trigger a claim and a burn of ETH.
* @param requestId request ID of the withdrawal to process
*/
function triggerBurn(
⋮----
/**
* @notice Trigger a batch claim and burn of ETH.
* @param requestIds request IDs of the withdrawals to process
* @param hints hints for the requests
*/
function triggerBurnBatch(uint256[] calldata requestIds, uint256[] calldata hints) external;
````
## File: src/interfaces/burners/wstETH/IWstETH.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IWstETH {
/**
* @notice Get amount of stETH for a given amount of wstETH
* @param _wstETHAmount amount of wstETH
* @return Amount of stETH for a given wstETH amount
*/
function getStETHByWstETH(
⋮----
/**
* @notice Exchanges wstETH to stETH
* @param _wstETHAmount amount of wstETH to uwrap in exchange for stETH
* @dev Requirements:
* - `_wstETHAmount` must be non-zero
* - msg.sender must have at least `_wstETHAmount` wstETH.
* @return Amount of stETH user receives after unwrap
*/
function unwrap(
````
## File: src/interfaces/common/IAddressRequests.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IAddressRequests {
⋮----
/**
* @notice Get the number of unprocessed request IDs.
*/
function requestIdsLength() external view returns (uint256);
⋮----
/**
* @notice Get a list of unprocessed request IDs.
* @param index index of the first request ID
* @param maxRequestIds maximum number of request IDs to return
* @return requestIds request IDs
*/
function requestIds(uint256 index, uint256 maxRequestIds) external view returns (address[] memory requestIds);
````
## File: src/interfaces/common/IUintRequests.sol
````
// SPDX-License-Identifier: MIT
⋮----
interface IUintRequests {
⋮----
/**
* @notice Get the number of unprocessed request IDs.
*/
function requestIdsLength() external view returns (uint256);
⋮----
/**
* @notice Get a list of unprocessed request IDs.
* @param index index of the first request ID
* @param maxRequestIds maximum number of request IDs to return
* @return requestIds request IDs
*/
function requestIds(uint256 index, uint256 maxRequestIds) external view returns (uint256[] memory requestIds);
````
## File: src/interfaces/router/IBurnerRouter.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBurner} from "@symbioticfi/core/src/interfaces/slasher/IBurner.sol";
⋮----
interface IBurnerRouter is IBurner {
⋮----
/**
* @notice Structure for a value of `address` type.
* @param value value of `address` type
*/
⋮----
/**
* @notice Structure for a pending value of `address` type.
* @param value pending value of `address` type
* @param timestamp timestamp since which the pending value can be used
*/
⋮----
/**
* @notice Structure for a value of `uint48` type.
* @param value value of `uint48` type
*/
⋮----
/**
* @notice Structure for a pending value of `uint48` type.
* @param value pending value of `uint48` type
* @param timestamp timestamp since which the pending value can be used
*/
⋮----
/**
* @notice Structure used to set a `receiver` for a slashing `network`.
* @param network address of the slashing network
* @param receiver address of the recipient of the slashed funds
*/
⋮----
/**
* @notice Structure used to set a `receiver` for a slashed `operator` by a slashing `network`.
* @param network address of the slashing network
* @param operator address of the slashed operator
* @param receiver address of the recipient of the slashed funds
*/
⋮----
/**
* @notice Initial parameters needed for a router deployment.
* @param owner manager of the router's receivers
* @param collateral router's underlying collateral (MUST be the same as the vault's underlying collateral)
* @param delay delay for setting a new receiver or changing the delay itself (in seconds)
* @param globalReceiver address of the global receiver of the slashed funds (if no receiver is set for a network or operator)
* @param networkReceivers array of network receivers to set on deployment (network => receiver)
* @param operatorNetworkReceivers array of operator network receivers to set on deployment (network-operator => receiver)
*/
⋮----
/**
* @notice Emitted when a transfer from the router to the receiver is triggered.
* @param receiver address of the receiver
* @param amount amount of the transfer
*/
event TriggerTransfer(address indexed receiver, uint256 amount);
⋮----
/**
* @notice Emitted when a global receiver is set (becomes pending for a `delay`).
* @param receiver address of the receiver
*/
event SetGlobalReceiver(address receiver);
⋮----
/**
* @notice Emitted when a pending global receiver is accepted.
*/
event AcceptGlobalReceiver();
⋮----
/**
* @notice Emitted when a network receiver is set (becomes pending for a `delay`).
* @param network address of the network
* @param receiver address of the receiver
*/
event SetNetworkReceiver(address indexed network, address receiver);
⋮----
/**
* @notice Emitted when a pending network receiver is accepted.
* @param network address of the network
*/
event AcceptNetworkReceiver(address indexed network);
⋮----
/**
* @notice Emitted when an operator network receiver is set (becomes pending for a `delay`).
* @param network address of the network
* @param operator address of the operator
* @param receiver address of the receiver
*/
event SetOperatorNetworkReceiver(address indexed network, address indexed operator, address receiver);
⋮----
/**
* @notice Emitted when a pending operator network receiver is accepted.
* @param network address of the network
* @param operator address of the operator
*/
event AcceptOperatorNetworkReceiver(address indexed network, address indexed operator);
⋮----
/**
* @notice Emitted when a delay is set (becomes pending for a `delay`).
* @param delay new delay
*/
event SetDelay(uint48 delay);
⋮----
/**
* @notice Emitted when a pending delay is accepted.
*/
event AcceptDelay();
⋮----
/**
* @notice Get a router collateral.
* @return address of the underlying collateral
*/
function collateral() external view returns (address);
⋮----
/**
* @notice Get a router last checked balance.
* @return last balance of the router
*/
function lastBalance() external view returns (uint256);
⋮----
/**
* @notice Get a router delay.
* @return delay for setting a new receiver or changing the delay itself (in seconds)
*/
function delay() external view returns (uint48);
⋮----
/**
* @notice Get a router pending delay.
* @return value pending delay
* @return timestamp timestamp since which the pending delay can be used
*/
function pendingDelay() external view returns (uint48, uint48);
⋮----
/**
* @notice Get a router global receiver.
* @return address of the global receiver of the slashed funds
*/
function globalReceiver() external view returns (address);
⋮----
/**
* @notice Get a router pending global receiver.
* @return value pending global receiver
* @return timestamp timestamp since which the pending global receiver can be used
*/
function pendingGlobalReceiver() external view returns (address, uint48);
⋮----
/**
* @notice Get a router receiver for a slashing network.
* @param network address of the slashing network
* @return address of the receiver
*/
function networkReceiver(
⋮----
/**
* @notice Get a router pending receiver for a slashing network.
* @param network address of the slashing network
* @return value pending receiver
* @return timestamp timestamp since which the pending receiver can be used
*/
function pendingNetworkReceiver(
⋮----
/**
* @notice Get a router receiver for a slashed operator by a slashing network.
* @param network address of the slashing network
* @param operator address of the slashed operator
* @return address of the receiver
*/
function operatorNetworkReceiver(address network, address operator) external view returns (address);
⋮----
/**
* @notice Get a router pending receiver for a slashed operator by a slashing network.
* @param network address of the slashing network
* @param operator address of the slashed operator
* @return value pending receiver
* @return timestamp timestamp since which the pending receiver can be used
*/
function pendingOperatorNetworkReceiver(
⋮----
/**
* @notice Get a receiver balance of unclaimed collateral.
* @param receiver address of the receiver
* @return amount of the unclaimed collateral tokens
*/
function balanceOf(
⋮----
/**
* @notice Trigger a transfer of the unclaimed collateral to the receiver.
* @param receiver address of the receiver
* @return amount of the transfer
*/
function triggerTransfer(
⋮----
/**
* @notice Set a new global receiver of the slashed funds.
* @param receiver address of the new receiver
*/
function setGlobalReceiver(
⋮----
/**
* @notice Accept a pending global receiver.
*/
function acceptGlobalReceiver() external;
⋮----
/**
* @notice Set a new receiver for a slashing network.
* @param network address of the slashing network
* @param receiver address of the new receiver
*/
function setNetworkReceiver(address network, address receiver) external;
⋮----
/**
* @notice Accept a pending receiver for a slashing network.
* @param network address of the slashing network
*/
function acceptNetworkReceiver(
⋮----
/**
* @notice Set a new receiver for a slashed operator by a slashing network.
* @param network address of the slashing network
* @param operator address of the slashed operator
* @param receiver address of the new receiver
*/
function setOperatorNetworkReceiver(address network, address operator, address receiver) external;
⋮----
/**
* @notice Accept a pending receiver for a slashed operator by a slashing network.
* @param network address of the slashing network
* @param operator address of the slashed operator
*/
function acceptOperatorNetworkReceiver(address network, address operator) external;
⋮----
/**
* @notice Set a new delay for setting a new receiver or changing the delay itself.
* @param newDelay new delay (in seconds)
*/
function setDelay(
⋮----
/**
* @notice Accept a pending delay.
*/
function acceptDelay() external;
````
## File: src/interfaces/router/IBurnerRouterFactory.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBurnerRouter} from "./IBurnerRouter.sol";
⋮----
import {IRegistry} from "@symbioticfi/core/src/interfaces/common/IRegistry.sol";
⋮----
interface IBurnerRouterFactory is IRegistry {
/**
* @notice Create a burner router contract.
* @param params initial parameters needed for a burner router contract deployment
* @return address of the created burner router contract
*/
function create(
````
## File: test/burners/ETHx_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {ETHx_Burner} from "../../src/contracts/burners/ETHx_Burner.sol";
⋮----
import {IETHx_Burner} from "../../src/interfaces/burners/ETHx/IETHx_Burner.sol";
import {IStaderConfig} from "../../src/interfaces/burners/ETHx/IStaderConfig.sol";
import {IStaderStakePoolsManager} from "../../src/interfaces/burners/ETHx/IStaderStakePoolsManager.sol";
import {IUserWithdrawalManager} from "../../src/interfaces/burners/ETHx/IUserWithdrawalManager.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract ETHx_BurnerTest is Test {
⋮----
// in shares
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(
⋮----
function test_TriggerWithdrawalRevertInvalidHints(uint256 depositAmount1, uint256 withdrawRequestMaximum_) public {
⋮----
function test_TriggerBurn(
⋮----
function test_TriggerBurnRevertInvalidRequestId(
⋮----
interface IETHx {
/**
* @notice Mints ethX when called by an authorized caller
* @param to the account to mint to
* @param amount the amount of ethX to mint
*/
function mint(address to, uint256 amount) external;
````
## File: test/burners/mETH_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {mETH_Burner} from "../../src/contracts/burners/mETH_Burner.sol";
⋮----
import {IStaking} from "../../src/interfaces/burners/mETH/IStaking.sol";
import {IMETH} from "../../src/interfaces/burners/mETH/IMETH.sol";
import {ImETH_Burner} from "../../src/interfaces/burners/mETH/ImETH_Burner.sol";
import {IUintRequests} from "../../src/interfaces/common/IUintRequests.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract mETH_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(uint256 depositAmount1, uint256 depositAmount2) public {
⋮----
function test_TriggerBurn(
⋮----
function test_TriggerBurnRevertInvalidRequestId(
⋮----
interface ITransparentUpgradeableProxy {
function admin() external view returns (address);
⋮----
function implementation() external view returns (address);
⋮----
function changeAdmin(
⋮----
function upgradeTo(
⋮----
function upgradeToAndCall(address, bytes memory) external payable;
⋮----
interface IUnstakeRequestsManagerWrite {
/// @notice Returns the ID of the next unstake requests to be created.
function nextRequestId() external view returns (uint256);
⋮----
/// @notice Allocate ether into the contract.
/// @dev Handles incoming ether from the staking contract, increasing the allocatedETHForClaims counter by the value
/// of the incoming allocatedETH.
function allocateETH() external payable;
⋮----
interface IOracle {
/// @notice The records stored by the oracle contract informing the protocol about consensus layer activity. It is
/// computed and reported by off-chain oracle services.
/// @dev "current" quantities refer to the state at the `updateEndBlock` block number.
/// @dev "cumulative" quantities refer to sums up to the `updateEndBlock` block number.
/// @dev "window" quantities refer to sums over the block window between the `updateStartBlock` and `updateEndBlock`.
/// @param updateStartBlock The start of the oracle record block window. This should be 1 higher than the
/// updateEndBlock of the previous oracle record.
/// @param updateEndBlock The block number up to which this oracle record was computed (inclusive).
/// @param currentNumValidatorsNotWithdrawable The number of our validators that do not have the withdrawable status.
/// @param cumulativeNumValidatorsWithdrawable The total number of our validators that have the withdrawable status.
/// These validators have either the status `withdrawal_possible` or `withdrawal_done`. Note: validators can
/// fluctuate between the two statuses due to top ups.
/// @param windowWithdrawnPrincipalAmount The amount of principal that has been withdrawn from the consensus layer in
/// the analyzed block window.
/// @param windowWithdrawnRewardAmount The amount of rewards that has been withdrawn from the consensus layer in the
/// analysed block window.
/// @param currentTotalValidatorBalance The total amount of ETH in the consensus layer (i.e. the sum of all validator
/// balances). This is one of the major quantities to compute the total value controlled by the protocol.
/// @param cumulativeProcessedDepositAmount The total amount of ETH that has been deposited into and processed by the
/// consensus layer. This is used to prevent double counting of the ETH deposited to the consensus layer.
⋮----
/// @notice Returns the latest validated record.
/// @return `OracleRecord` The latest validated record.
function latestRecord() external view returns (OracleRecord memory);
⋮----
contract Oracle is IOracle {
function latestRecord() external view override returns (OracleRecord memory) {
````
## File: test/burners/rETH_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {rETH_Burner} from "../../src/contracts/burners/rETH_Burner.sol";
⋮----
import {IrETH_Burner} from "../../src/interfaces/burners/rETH/IrETH_Burner.sol";
import {IRocketTokenRETH} from "../../src/interfaces/burners/rETH/IRocketTokenRETH.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract rETH_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerBurn(uint256 depositAmount1, uint256 burnAmount1, uint256 burnAmount2) public {
⋮----
function test_TriggerBurnRevert(uint256 depositAmount1, uint256 burnAmount1) public {
````
## File: test/burners/sfrxETH_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {sfrxETH_Burner} from "../../src/contracts/burners/sfrxETH_Burner.sol";
⋮----
import {IFraxEtherRedemptionQueue} from "../../src/interfaces/burners/sfrxETH/IFraxEtherRedemptionQueue.sol";
import {IsfrxETH_Burner} from "../../src/interfaces/burners/sfrxETH/IsfrxETH_Burner.sol";
import {IUintRequests} from "../../src/interfaces/common/IUintRequests.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract sfrxETH_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(uint256 depositAmount1, uint256 depositAmount2) public {
⋮----
function test_TriggerBurn(
⋮----
function test_TriggerBurnRevertInvalidRequestId(
⋮----
interface IFrxETH {
// This function is what other minters will call to mint new tokens
function minter_mint(address m_address, uint256 m_amount) external;
⋮----
interface ISfrxETH {
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
````
## File: test/burners/sUSDe_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {sUSDe_Burner} from "../../src/contracts/burners/sUSDe/sUSDe_Burner.sol";
import {sUSDe_Miniburner} from "../../src/contracts/burners/sUSDe/sUSDe_Miniburner.sol";
⋮----
import {IsUSDe_Burner} from "../../src/interfaces/burners/sUSDe/IsUSDe_Burner.sol";
import {ISUSDe} from "../../src/interfaces/burners/sUSDe/ISUSDe.sol";
import {IUSDe} from "../../src/interfaces/burners/sUSDe/IUSDe.sol";
import {IEthenaMinting} from "../../src/interfaces/burners/sUSDe/IEthenaMinting.sol";
import {IAddressRequests} from "../../src/interfaces/common/IAddressRequests.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract sUSDe_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(uint256 depositAmount1, uint256 depositAmount2, uint24 duration) public {
⋮----
function test_TriggerClaim(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerClaimRevertInvalidRequestId(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerClaimRevertNoCooldown(
⋮----
function test_TriggerInstantClaim(
⋮----
function test_TriggerInstantClaimRevertHasCooldown(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerBurn1(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerBurn2(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerBurnRevertInvalidAsset1(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_TriggerBurnRevertInvalidAsset2(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_ApproveUSDeMinter(uint256 depositAmount1, uint24 duration) public {
⋮----
function test_ApproveUSDeMinterRevertSufficientAllowance(uint256 depositAmount1, uint24 duration) public {
````
## File: test/burners/swETH_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {swETH_Burner} from "../../src/contracts/burners/swETH_Burner.sol";
⋮----
import {ISwEXIT} from "../../src/interfaces/burners/swETH/ISwEXIT.sol";
import {ISwETH} from "../../src/interfaces/burners/swETH/ISwETH.sol";
import {IswETH_Burner} from "../../src/interfaces/burners/swETH/IswETH_Burner.sol";
import {IUintRequests} from "../../src/interfaces/common/IUintRequests.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract swETH_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(uint256 depositAmount1, uint256 depositAmount2, uint256 maxRequests) public {
⋮----
function test_TriggerWithdrawalRevertInsufficientWithdrawal(
⋮----
function test_TriggerBurn(
⋮----
function test_TriggerBurnRevertInvalidRequestId(
````
## File: test/burners/wstETH_Burner.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {wstETH_Burner} from "../../src/contracts/burners/wstETH_Burner.sol";
⋮----
import {IWithdrawalQueue} from "../../src/interfaces/burners/wstETH/IWithdrawalQueue.sol";
import {IWstETH} from "../../src/interfaces/burners/wstETH/IWstETH.sol";
import {IwstETH_Burner} from "../../src/interfaces/burners/wstETH/IwstETH_Burner.sol";
import {IUintRequests} from "../../src/interfaces/common/IUintRequests.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
⋮----
contract wstETH_BurnerTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
⋮----
function test_TriggerWithdrawal(uint256 depositAmount1, uint256 depositAmount2, uint256 maxRequests) public {
⋮----
function test_TriggerWithdrawalRevertInsufficientWithdrawal(
⋮----
function test_TriggerBurn(
⋮----
function test_TriggerBurnRevertInvalidRequestId(
⋮----
function test_TriggerBurnBatch(
⋮----
function test_TriggerBurnBatchRevertInvalidRequestId(
````
## File: test/common/SelfDestruct.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test, console2} from "forge-std/Test.sol";
⋮----
import {SelfDestruct} from "../../src/contracts/common/SelfDestruct.sol";
⋮----
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
⋮----
contract SelfDestructTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create() public {
````
## File: test/integration/SymbioticBurnersBindings.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticBurnersImports.sol";
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
contract SymbioticBurnersBindings is Test {
function _createBurnerRouter_SymbioticBurners(
⋮----
function _triggerTransfer_SymbioticBurners(address who, address burnerRouter, address receiver) internal virtual {
⋮----
function _setGlobalReceiver_SymbioticBurners(
⋮----
function _acceptGlobalReceiver_SymbioticBurners(address who, address burnerRouter) internal virtual {
⋮----
function _setNetworkReceiver_SymbioticBurners(
⋮----
function _acceptNetworkReceiver_SymbioticBurners(
⋮----
function _setOperatorNetworkReceiver_SymbioticBurners(
⋮----
function _acceptOperatorNetworkReceiver_SymbioticBurners(
⋮----
function _setDelay_SymbioticBurners(address who, address burnerRouter, uint48 newDelay) internal virtual {
⋮----
function _acceptDelay_SymbioticBurners(address who, address burnerRouter) internal virtual {
⋮----
function _triggerWithdrawal_ETHx_SymbioticBurners(
⋮----
function _triggerBurn_ETHx_SymbioticBurners(address who, address burner, uint256 requestId) internal virtual {
⋮----
function _triggerWithdrawal_mETH_SymbioticBurners(
⋮----
function _triggerBurn_mETH_SymbioticBurners(address who, address burner, uint256 requestId) internal virtual {
⋮----
function _triggerBurn_rETH_SymbioticBurners(address who, address burner, uint256 amount) internal virtual {
⋮----
function _triggerWithdrawal_sfrxETH_SymbioticBurners(
⋮----
function _triggerBurn_sfrxETH_SymbioticBurners(address who, address burner, uint256 requestId) internal virtual {
⋮----
function _triggerWithdrawal_sUSDe_SymbioticBurners(
⋮----
function _triggerClaim_sUSDe_SymbioticBurners(address who, address burner, address requestId) internal virtual {
⋮----
function _triggerInstantClaim_sUSDe_SymbioticBurners(address who, address burner) internal virtual {
⋮----
function _triggerBurn_sUSDe_SymbioticBurners(address who, address burner, address asset) internal virtual {
⋮----
function _approveUSDeMinter_sUSDe_SymbioticBurners(address who, address burner) internal virtual {
⋮----
function _triggerWithdrawal_swETH_SymbioticBurners(
⋮----
function _triggerBurn_swETH_SymbioticBurners(address who, address burner, uint256 requestId) internal virtual {
⋮----
function _triggerWithdrawal_wstETH_SymbioticBurners(
⋮----
function _triggerBurn_wstETH_SymbioticBurners(address who, address burner, uint256 requestId) internal virtual {
⋮----
function _triggerBurnBatch_wstETH_SymbioticBurners(
````
## File: test/integration/SymbioticBurnersConstants.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticBurnersImports.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
import {SymbioticCoreConstants} from "@symbioticfi/core/test/integration/SymbioticCoreConstants.sol";
⋮----
function burners() internal view returns (Burners memory) {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
⋮----
// hoodi
⋮----
function burnerRouterFactory() internal view returns (ISymbioticBurnerRouterFactory) {
⋮----
function ETHx_BurnerSupported() internal view returns (bool) {
⋮----
function mETH_BurnerSupported() internal view returns (bool) {
⋮----
function rETH_BurnerSupported() internal view returns (bool) {
⋮----
function sfrxETH_BurnerSupported() internal view returns (bool) {
⋮----
function swETH_BurnerSupported() internal view returns (bool) {
⋮----
function wstETH_BurnerSupported() internal view returns (bool) {
⋮----
function burner(
⋮----
function burnerSupported(
⋮----
function allBurners() internal view returns (string[] memory result) {
⋮----
function tokenAddressToBurner(
⋮----
function tokenAddressToBurnerSupported(
⋮----
function lidoWithdrawalQueue() internal view returns (address) {
⋮----
function swEXIT() internal view returns (address) {
⋮----
function fraxEtherRedemptionQueue() internal view returns (address) {
⋮----
function staderConfig() internal view returns (address) {
````
## File: test/integration/SymbioticBurnersImports.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IBurnerRouter as ISymbioticBurnerRouter} from "../../src/interfaces/router/IBurnerRouter.sol";
import {IBurnerRouterFactory as ISymbioticBurnerRouterFactory} from
"../../src/interfaces/router/IBurnerRouterFactory.sol";
import {IAddressRequests as ISymbioticAddressRequests} from "../../src/interfaces/common/IAddressRequests.sol";
import {IUintRequests as ISymbioticUintRequests} from "../../src/interfaces/common/IUintRequests.sol";
import {IETHx_Burner as ISymbioticETHx_Burner} from "../../src/interfaces/burners/ETHx/IETHx_Burner.sol";
import {ImETH_Burner as ISymbioticmETH_Burner} from "../../src/interfaces/burners/mETH/ImETH_Burner.sol";
import {IrETH_Burner as ISymbioticrETH_Burner} from "../../src/interfaces/burners/rETH/IrETH_Burner.sol";
import {IsfrxETH_Burner as ISymbioticsfrxETH_Burner} from "../../src/interfaces/burners/sfrxETH/IsfrxETH_Burner.sol";
import {IsUSDe_Burner as ISymbioticsUSDe_Burner} from "../../src/interfaces/burners/sUSDe/IsUSDe_Burner.sol";
import {IswETH_Burner as ISymbioticswETH_Burner} from "../../src/interfaces/burners/swETH/IswETH_Burner.sol";
import {IwstETH_Burner as ISymbioticwstETH_Burner} from "../../src/interfaces/burners/wstETH/IwstETH_Burner.sol";
⋮----
interface SymbioticBurnersImports {}
````
## File: test/integration/SymbioticBurnersImportsContracts.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {BurnerRouter as SymbioticBurnerRouter} from "../../src/contracts/router/BurnerRouter.sol";
import {BurnerRouterFactory as SymbioticBurnerRouterFactory} from "../../src/contracts/router/BurnerRouterFactory.sol";
import {AddressRequests as SymbioticAddressRequests} from "../../src/contracts/common/AddressRequests.sol";
import {UintRequests as SymbioticUintRequests} from "../../src/contracts/common/UintRequests.sol";
import {SelfDestruct as SymbioticSelfDestruct} from "../../src/contracts/common/SelfDestruct.sol";
import {ETHx_Burner as SymbioticETHx_Burner} from "../../src/contracts/burners/ETHx_Burner.sol";
import {mETH_Burner as SymbioticmETH_Burner} from "../../src/contracts/burners/mETH_Burner.sol";
import {rETH_Burner as SymbioticrETH_Burner} from "../../src/contracts/burners/rETH_Burner.sol";
import {sfrxETH_Burner as SymbioticsfrxETH_Burner} from "../../src/contracts/burners/sfrxETH_Burner.sol";
import {
sUSDe_Burner as SymbioticsUSDe_Burner,
sUSDe_Miniburner as SymbioticsUSDe_Miniburner
} from "../../src/contracts/burners/sUSDe/sUSDe_Burner.sol";
import {swETH_Burner as SymbioticswETH_Burner} from "../../src/contracts/burners/swETH_Burner.sol";
import {wstETH_Burner as SymbioticwstETH_Burner} from "../../src/contracts/burners/wstETH_Burner.sol";
⋮----
interface SymbioticBurnersImportsContracts {}
````
## File: test/integration/SymbioticBurnersInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreInit.sol";
⋮----
import "./SymbioticBurnersImports.sol";
⋮----
import {SymbioticBurnersConstants} from "./SymbioticBurnersConstants.sol";
import {SymbioticBurnersBindings} from "./SymbioticBurnersBindings.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract SymbioticBurnersInit is SymbioticCoreInit, SymbioticBurnersBindings {
⋮----
// General config
⋮----
// Burner Router config
⋮----
function setUp() public virtual override {
⋮----
// ------------------------------------------------------------ GENERAL HELPERS ------------------------------------------------------------ //
⋮----
function _initBurners_SymbioticBurners() internal virtual {
⋮----
function _initBurners_SymbioticBurners(
⋮----
function _initBurnerRouter_SymbioticBurners() internal virtual {
⋮----
function _initBurnerRouter_SymbioticBurners(
⋮----
// ------------------------------------------------------------ BURNER-ROUTER-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getBurnerRouter_SymbioticBurners(
⋮----
function _getBurnerRouterRandom_SymbioticBurners(
⋮----
// ------------------------------------------------------------ ANYONE-RELATED HELPERS ------------------------------------------------------------ //
⋮----
// function _anyoneTriggerAction_SymbioticBurners(
// address anyone,
// address burner
// ) internal virtual returns (bool lastStep) {
// // address collateral = ISymbioticETHx_Burner(burner).COLLATERAL();
// // address collateral = ISymbioticmETH_Burner(burner).COLLATERAL();
// // address collateral = ISymbioticrETH_Burner(burner).COLLATERAL();
// // address collateral = ISymbioticsfrxETH_Burner(burner).COLLATERAL();
// // address collateral = ISymbioticswETH_Burner(burner).COLLATERAL();
// address collateral = ISymbioticwstETH_Burner(burner).COLLATERAL();
⋮----
// if (collateral == SymbioticCoreConstants.token("ETHx")) {
// ;
// return false;
// } else if (collateral == SymbioticCoreConstants.token("mETH")) {
⋮----
// } else if (collateral == SymbioticCoreConstants.token("rETH")) {
⋮----
// return true;
// } else if (collateral == SymbioticCoreConstants.token("sfrxETH")) {
⋮----
// } else if (collateral == SymbioticCoreConstants.token("swETH")) {
⋮----
// } else if (collateral == SymbioticCoreConstants.token("wstETH")) {
⋮----
// } else {
// revert("Unsupported collateral");
// }
// }
⋮----
function _anyoneTriggerTransfer_SymbioticBurners(
⋮----
function _anyoneAcceptGlobalReceiver_SymbioticBurners(address anyone, address burnerRouter) internal virtual {
⋮----
function _anyoneAcceptNetworkReceiver_SymbioticBurners(
⋮----
function _anyoneAcceptOperatorNetworkReceiver_SymbioticBurners(
⋮----
function _anyoneAcceptDelay_SymbioticBurners(address anyone, address burnerRouter) internal virtual {
⋮----
// ------------------------------------------------------------ CURATOR-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _curatorSetGlobalReceiver_SymbioticBurners(
⋮----
function _curatorSetNetworkReceiver_SymbioticBurners(
⋮----
function _curatorSetOperatorNetworkReceiver_SymbioticBurners(
⋮----
function _curatorSetDelay_SymbioticBurners(address curator, address burnerRouter, uint48 delay) internal virtual {
````
## File: test/integration/SymbioticBurnersIntegration.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreIntegration.sol";
⋮----
import "./SymbioticBurnersInit.sol";
⋮----
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
⋮----
contract SymbioticBurnersIntegration is SymbioticBurnersInit, SymbioticCoreIntegration {
⋮----
function setUp() public virtual override(SymbioticBurnersInit, SymbioticCoreIntegration) {
⋮----
function _getVaultRandom_SymbioticCore(
⋮----
// New code
````
## File: test/integration/SymbioticBurnersIntegrationExample.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticBurnersIntegration.sol";
⋮----
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
⋮----
import {console2} from "forge-std/Test.sol";
⋮----
contract SymbioticBurnersIntegrationExample is SymbioticBurnersIntegration {
⋮----
uint256 public SELECT_OPERATOR_CHANCE = 1; // lower -> higher probability
⋮----
function setUp() public override {
⋮----
// vm.selectFork(vm.createFork(vm.rpcUrl("holesky")));
// SYMBIOTIC_INIT_BLOCK = 2_727_202;
// SYMBIOTIC_CORE_USE_EXISTING_DEPLOYMENT = true;
// SYMBIOTIC_BURNERS_USE_EXISTING_DEPLOYMENT = true;
⋮----
function test_NetworkWithCustomBurner() public {
⋮----
_skipBlocks_Symbiotic(SYMBIOTIC_BURNERS_MAX_DELAY); // for simplicity
````
## File: test/router/BurnerRouter.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "@symbioticfi/core/src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "@symbioticfi/core/src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "@symbioticfi/core/src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "@symbioticfi/core/src/contracts/OperatorRegistry.sol";
import {MetadataService} from "@symbioticfi/core/src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "@symbioticfi/core/src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "@symbioticfi/core/src/contracts/slasher/VetoSlasher.sol";
⋮----
import {Token} from "@symbioticfi/core/test/mocks/Token.sol";
import {VaultConfigurator, IVaultConfigurator} from "@symbioticfi/core/src/contracts/VaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {BurnerRouterFactory} from "../../src/contracts/router/BurnerRouterFactory.sol";
import {BurnerRouter} from "../../src/contracts/router/BurnerRouter.sol";
import {IBurnerRouter} from "../../src/interfaces/router/IBurnerRouter.sol";
⋮----
contract BurnerRouterTest is Test {
⋮----
function setUp() public {
⋮----
function test_SetGlobalReceiver() external {
⋮----
function test_SetGlobalReceiverRevertAlreadySet() external {
⋮----
function test_AcceptGlobalReceiver() external {
⋮----
function test_AcceptGlobalReceiverRevertNotReady() external {
⋮----
function test_SetNetworkReceiver() external {
⋮----
function test_SetNetworkReceiverRevertAlreadySet() external {
⋮----
function test_AcceptNetworkReceiver() external {
⋮----
function test_AcceptNetworkReceiverRevertNotReady() external {
⋮----
function test_SetOperatorNetworkReceiver() external {
⋮----
function test_SetOperatorNetworkReceiverRevertAlreadySet() external {
⋮----
function test_AcceptOperatorNetworkReceiver() external {
⋮----
function test_AcceptOperatorNetworkReceiverRevertNotReady() external {
⋮----
function test_SetDelay() external {
⋮----
function test_SetDelayRevertAlreadySet() external {
⋮----
function test_AcceptDelay() external {
⋮----
function test_AcceptDelayRevertNotReady() external {
⋮----
function test_OnSlash(uint256 amount1, uint256 amount2, uint256 amount3) external {
⋮----
function test_TriggerTransfer(uint256 amount1, uint256 amount2, uint256 amount3) external {
⋮----
function test_TriggerTransferRevertInsufficientBalance(
⋮----
function _getVaultWithDelegatorWithSlasher(
````
## File: test/router/BurnerRouterFactory.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
import {VaultFactory} from "@symbioticfi/core/src/contracts/VaultFactory.sol";
import {DelegatorFactory} from "@symbioticfi/core/src/contracts/DelegatorFactory.sol";
import {SlasherFactory} from "@symbioticfi/core/src/contracts/SlasherFactory.sol";
import {NetworkRegistry} from "@symbioticfi/core/src/contracts/NetworkRegistry.sol";
import {OperatorRegistry} from "@symbioticfi/core/src/contracts/OperatorRegistry.sol";
import {MetadataService} from "@symbioticfi/core/src/contracts/service/MetadataService.sol";
import {NetworkMiddlewareService} from "@symbioticfi/core/src/contracts/service/NetworkMiddlewareService.sol";
import {OptInService} from "@symbioticfi/core/src/contracts/service/OptInService.sol";
⋮----
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {VetoSlasher} from "@symbioticfi/core/src/contracts/slasher/VetoSlasher.sol";
⋮----
import {Token} from "@symbioticfi/core/test/mocks/Token.sol";
import {VaultConfigurator, IVaultConfigurator} from "@symbioticfi/core/src/contracts/VaultConfigurator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
⋮----
import {BurnerRouterFactory} from "../../src/contracts/router/BurnerRouterFactory.sol";
import {BurnerRouter} from "../../src/contracts/router/BurnerRouter.sol";
import {IBurnerRouter} from "../../src/interfaces/router/IBurnerRouter.sol";
⋮----
contract BurnerRouterFactoryTest is Test {
⋮----
function setUp() public {
⋮----
function test_Create(uint48 delay, address globalReceiver) public {
⋮----
function test_CreateRevertInvalidCollateral(uint48 delay, address globalReceiver) public {
⋮----
function test_CreateRevertInvalidReceiver1(uint48 delay, address globalReceiver) public {
⋮----
function test_CreateRevertInvalidReceiver2(uint48 delay, address globalReceiver) public {
⋮----
function test_CreateRevertDuplicateNetworkReceiver(uint48 delay, address globalReceiver) public {
⋮----
function test_CreateRevertDuplicateOperatorNetworkReceiver(uint48 delay, address globalReceiver) public {
⋮----
function _getVaultWithDelegatorWithSlasher(
````
## File: .env.example
````
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
````
## File: .gitignore
````
# Compiler files
cache/
out/**/
!out/sUSDe_Burner.sol/
!out/sUSDe_Minburner.sol/
!out/ETHx_Burner.sol/
!out/mETH_Burner.sol/
!out/rETH_Burner.sol/
!out/sfrxETH_Burner.sol/
!out/swETH_Burner.sol/
!out/wstETH_Burner.sol/
!out/BurnerRouterFactory.sol/
!out/BurnerRouter.sol/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/*/11155111/
/broadcast/**/dry-run/
# Docs
docs/
# Dotenv file
.env
# Other files
.gas-snapshot
lcov.info
````
## File: .gitmodules
````
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/core"]
path = lib/core
url = https://github.com/symbioticfi/core
````
## File: foundry.toml
````toml
[profile.default]
evm_version = "cancun"
solc = "0.8.25"
optimizer = true
optimizer_runs = 200
via_ir = true
src = "src"
out = "out"
libs = ["lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
gas_reports = ["*"]
gas_limit = "18446744073709551615"
[rpc_endpoints]
mainnet = "${ETH_RPC_URL}"
holesky = "${ETH_RPC_URL_HOLESKY}"
[fmt]
bracket_spacing = false
int_types = "long"
line_length = 120
multiline_func_header = "params_first"
number_underscore = "thousands"
quote_style = "double"
tab_width = 4
[fuzz]
runs = 4096
max_test_rejects = 262144
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
````
## File: LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: package.json
````json
{
"name": "@symbioticfi/burners",
"version": "1.0.0",
"description": "Symbiotic Burners repository contains an implementation of Burner Router allowing the construction of flexible on-slash burning mechanics and several pure Burners for different assets.",
"homepage": "https://symbiotic.fi/",
"bugs": "https://github.com/symbioticfi/burners/issues",
"license": "MIT",
"author": "Symbiotic Team",
"files": [
"src/**/*",
"test/mocks/**/*",
"out/**/*.json"
],
"repository": {
"type": "git",
"url": "https://github.com/symbioticfi/burners.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security"
],
"dependencies": {
"@openzeppelin/contracts": "5.0.2",
"@openzeppelin/contracts-upgradeable": "5.0.2",
"@symbioticfi/core": "1.0.0-devnet.9"
}
}
````
## File: README.md
````markdown
**[Symbiotic Protocol](https://symbiotic.fi) is an extremely flexible and permissionless shared security system.**
This repository contains Symbiotic Default Burners contracts.
[](https://deepwiki.com/symbioticfi/burners)
## Technical Documentation
Technical documentation can be found [here](./specs).
## Security
Security audits can be found [here](./audits).
Not included files:
- [`src/contracts/burners/sUSDe`](src/contracts/burners/sUSDe)
## Usage
### Env
Create `.env` file using a template:
```
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
```
\* ETH_RPC_URL is optional. \* ETH_RPC_URL_HOLESKY is optional. \* ETHERSCAN_API_KEY is optional.
### Build
```shell
forge build
```
### Test
```shell
forge test
```
### Format
```shell
forge fmt
```
### Gas Snapshots
```shell
forge snapshot
```
````
## File: remappings.txt
````
forge-std/=lib/forge-std/src/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@symbioticfi/core/=lib/core/
````
---
## Hooks
This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).
# File Summary
## Purpose
This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
## File Format
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A header with the file path (## File: path/to/file)
b. The full contents of the file in a code block
## Usage Guidelines
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
## Notes
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching these patterns are excluded: docs/
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)
# Directory Structure
```
.github/
workflows/
lint.yml
test.yml
audits/
Statemind-Hooks.pdf
script/
deploy/
FullRestakeDecreaseHook.s.sol
FullRestakeResetHook.s.sol
Hooks.s.sol
NetworkRestakeDecreaseHook.s.sol
NetworkRestakeRedistributeHook.s.sol
NetworkRestakeResetHook.s.sol
OperatorSpecificDecreaseHook.s.sol
OperatorSpecificResetHook.s.sol
specs/
FullRestakeDelegatorHooks.md
NetworkRestakeDelegatorHooks.md
OperatorSpecificDelegatorHooks.md
src/
contracts/
fullRestakeDelegator/
FullRestakeDecreaseHook.sol
FullRestakeResetHook.sol
networkRestakeDelegator/
NetworkRestakeDecreaseHook.sol
NetworkRestakeRedistributeHook.sol
NetworkRestakeResetHook.sol
operatorSpecificDelegator/
OperatorSpecificDecreaseHook.sol
OperatorSpecificResetHook.sol
interfaces/
fullRestakeDelegator/
IFullRestakeDecreaseHook.sol
IFullRestakeResetHook.sol
networkRestakeDelegator/
INetworkRestakeDecreaseHook.sol
INetworkRestakeRedistributeHook.sol
INetworkRestakeResetHook.sol
operatorSpecificDelegator/
IOperatorSpecificDecreaseHook.sol
IOperatorSpecificResetHook.sol
test/
fullRestakeDelegator/
FullRestakeDecreaseHook.t.sol
FullRestakeResetHook.t.sol
integration/
SymbioticHooksBindings.sol
SymbioticHooksConstants.sol
SymbioticHooksImports.sol
SymbioticHooksImportsContracts.sol
SymbioticHooksInit.sol
SymbioticHooksIntegration.sol
SymbioticHooksIntegrationExample.sol
mocks/
FakeDelegator.sol
networkRestakeDelegator/
NetworkRestakeDecreaseHook.t.sol
NetworkRestakeRedistributeHook.t.sol
NetworkRestakeResetHook.t.sol
operatorSpecificDelegator/
OperatorSpecificDecreaseHook.t.sol
OperatorSpecificResetHook.t.sol
.env.example
.gitignore
.gitmodules
foundry.toml
LICENSE
package.json
README.md
remappings.txt
```
# Files
## File: .github/workflows/lint.yml
````yaml
name: lint
on:
push:
branches:
- main
pull_request:
jobs:
run-linters:
name: Run linters
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v3
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Lint
run: forge fmt --check
````
## File: .github/workflows/test.yml
````yaml
name: test
on:
push:
branches:
- main
pull_request:
jobs:
run-tests:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Run Forge tests
run: |
forge test -vvv
id: test
````
## File: script/deploy/FullRestakeDecreaseHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {FullRestakeDecreaseHook} from "../../src/contracts/fullRestakeDelegator/FullRestakeDecreaseHook.sol";
⋮----
contract FullRestakeDecreaseHookScript is Script {
function run() public {
````
## File: script/deploy/FullRestakeResetHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {FullRestakeResetHook} from "../../src/contracts/fullRestakeDelegator/FullRestakeResetHook.sol";
⋮----
contract FullRestakeResetHookScript is Script {
function run(uint48 period, uint256 slashCount) public {
````
## File: script/deploy/Hooks.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {FullRestakeDecreaseHook} from "../../src/contracts/fullRestakeDelegator/FullRestakeDecreaseHook.sol";
import {NetworkRestakeDecreaseHook} from "../../src/contracts/networkRestakeDelegator/NetworkRestakeDecreaseHook.sol";
import {NetworkRestakeRedistributeHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeRedistributeHook.sol";
import {OperatorSpecificDecreaseHook} from
"../../src/contracts/operatorSpecificDelegator/OperatorSpecificDecreaseHook.sol";
⋮----
contract HooksScript is Script {
function run() public {
````
## File: script/deploy/NetworkRestakeDecreaseHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {NetworkRestakeDecreaseHook} from "../../src/contracts/networkRestakeDelegator/NetworkRestakeDecreaseHook.sol";
⋮----
contract NetworkRestakeDecreaseHookScript is Script {
function run() public {
````
## File: script/deploy/NetworkRestakeRedistributeHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {NetworkRestakeRedistributeHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeRedistributeHook.sol";
⋮----
contract NetworkRestakeRedistributeHookScript is Script {
function run() public {
````
## File: script/deploy/NetworkRestakeResetHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {NetworkRestakeResetHook} from "../../src/contracts/networkRestakeDelegator/NetworkRestakeResetHook.sol";
⋮----
contract NetworkRestakeResetHookScript is Script {
function run(uint48 period, uint256 slashCount) public {
````
## File: script/deploy/OperatorSpecificDecreaseHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {OperatorSpecificDecreaseHook} from
"../../src/contracts/operatorSpecificDelegator/OperatorSpecificDecreaseHook.sol";
⋮----
contract OperatorSpecificDecreaseHookScript is Script {
function run() public {
````
## File: script/deploy/OperatorSpecificResetHook.s.sol
````
// SPDX-License-Identifier: BUSL-1.1
⋮----
import {Script, console2} from "forge-std/Script.sol";
⋮----
import {OperatorSpecificResetHook} from "../../src/contracts/operatorSpecificDelegator/OperatorSpecificResetHook.sol";
⋮----
contract OperatorSpecificResetHookScript is Script {
function run(uint48 period, uint256 slashCount) public {
````
## File: specs/FullRestakeDelegatorHooks.md
````markdown
## Hooks
### FullRestakeDecreaseHook
FullRestakeDecreaseHook supports `onSlash()` calls only from `FullRestakeDelegator`.
This hook decreases the network's limit by the slashed amount and decreases the operator's limit also by the slashed amount. It doesn't change stake amounts for other operators.
### FullRestakeResetHook
FullRestakeResetHook supports `onSlash()` calls only from `FullRestakeDelegator`.
This hook resets the slashed operator's limit to zero in case it was slashed a configured number of times during a configured period of time.
````
## File: specs/NetworkRestakeDelegatorHooks.md
````markdown
## Hooks
### NetworkRestakeDecreaseHook
NetworkRestakeDecreaseHook supports `onSlash()` calls only from `NetworkRestakeDelegator`.
This hook decreases the network’s limit by the slashed amount and decreases the slashed operator’s shares (in case of network limit less than or equal to the active deposits, the stake will be decreased by the slashed amount, not changing other operators' stakes, otherwise, the stake changes depend on the active deposits).
### NetworkRestakeRedistributeHook
NetworkRestakeRedistributeHook supports `onSlash()` calls only from `NetworkRestakeDelegator`.
This hook decreases the slashed operator's shares by slashed percent from the given stake, redistributing the decreased stake to other operators.
### NetworkRestakeResetHook
NetworkRestakeResetHook supports `onSlash()` calls only from `NetworkRestakeDelegator`.
This hook resets the slashed operator's shares to zero in case it was slashed a configured number of times during a configured period of time.
````
## File: specs/OperatorSpecificDelegatorHooks.md
````markdown
## Hooks
### OperatorSpecificDecreaseHook
OperatorSpecificDecreaseHook supports `onSlash()` calls only from `OperatorSpecificDelegator`.
This hook decreases the network's limit by the slashed amount.
### OperatorSpecificResetHook
OperatorSpecificResetHook supports `onSlash()` calls only from `OperatorSpecificDelegator`.
This hook resets the slashing network's limit to zero in case it was slashed a configured number of times during a configured period of time.
````
## File: src/contracts/fullRestakeDelegator/FullRestakeDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFullRestakeDecreaseHook} from "../../interfaces/fullRestakeDelegator/IFullRestakeDecreaseHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {IFullRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/IFullRestakeDelegator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract FullRestakeDecreaseHook is IFullRestakeDecreaseHook {
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
⋮----
uint48, /* captureTimestamp */
bytes calldata /* data */
````
## File: src/contracts/fullRestakeDelegator/FullRestakeResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFullRestakeResetHook} from "../../interfaces/fullRestakeDelegator/IFullRestakeResetHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {IFullRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
⋮----
import {CircularBuffer} from "@openzeppelin/contracts/utils/structs/CircularBuffer.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract FullRestakeResetHook is IFullRestakeResetHook {
⋮----
/**
* @inheritdoc IFullRestakeResetHook
*/
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
⋮----
uint256, /* slashedAmount */
uint48, /* captureTimestamp */
bytes calldata /* data */
````
## File: src/contracts/networkRestakeDelegator/NetworkRestakeDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {INetworkRestakeDecreaseHook} from "../../interfaces/networkRestakeDelegator/INetworkRestakeDecreaseHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract NetworkRestakeDecreaseHook is INetworkRestakeDecreaseHook {
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
````
## File: src/contracts/networkRestakeDelegator/NetworkRestakeRedistributeHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {INetworkRestakeRedistributeHook} from
"../../interfaces/networkRestakeDelegator/INetworkRestakeRedistributeHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract NetworkRestakeRedistributeHook is INetworkRestakeRedistributeHook {
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
````
## File: src/contracts/networkRestakeDelegator/NetworkRestakeResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {INetworkRestakeResetHook} from "../../interfaces/networkRestakeDelegator/INetworkRestakeResetHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
⋮----
import {CircularBuffer} from "@openzeppelin/contracts/utils/structs/CircularBuffer.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract NetworkRestakeResetHook is INetworkRestakeResetHook {
⋮----
/**
* @inheritdoc INetworkRestakeResetHook
*/
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
⋮----
uint256, /* slashedAmount */
uint48, /* captureTimestamp */
bytes calldata /* data */
````
## File: src/contracts/operatorSpecificDelegator/OperatorSpecificDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOperatorSpecificDecreaseHook} from
"../../interfaces/operatorSpecificDelegator/IOperatorSpecificDecreaseHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {IOperatorSpecificDelegator} from "@symbioticfi/core/src/interfaces/delegator/IOperatorSpecificDelegator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract OperatorSpecificDecreaseHook is IOperatorSpecificDecreaseHook {
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
⋮----
address, /* operator */
⋮----
uint48, /* captureTimestamp */
bytes calldata /* data */
````
## File: src/contracts/operatorSpecificDelegator/OperatorSpecificResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IOperatorSpecificResetHook} from "../../interfaces/operatorSpecificDelegator/IOperatorSpecificResetHook.sol";
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
import {IEntity} from "@symbioticfi/core/src/interfaces/common/IEntity.sol";
import {IOperatorSpecificDelegator} from "@symbioticfi/core/src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
⋮----
import {CircularBuffer} from "@openzeppelin/contracts/utils/structs/CircularBuffer.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
⋮----
contract OperatorSpecificResetHook is IOperatorSpecificResetHook {
⋮----
/**
* @inheritdoc IOperatorSpecificResetHook
*/
⋮----
/**
* @inheritdoc IDelegatorHook
*/
function onSlash(
⋮----
address, /* operator */
uint256, /* slashedAmount */
uint48, /* captureTimestamp */
bytes calldata /* data */
````
## File: src/interfaces/fullRestakeDelegator/IFullRestakeDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface IFullRestakeDecreaseHook is IDelegatorHook {
````
## File: src/interfaces/fullRestakeDelegator/IFullRestakeResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface IFullRestakeResetHook is IDelegatorHook {
⋮----
/**
* @notice Get a period during which the slashing should occur to reset the operator's stake.
* @return threshold period
*/
function PERIOD() external view returns (uint48);
⋮----
/**
* @notice Get a number of slashes that should occur during the PERIOD to reset the operator's stake.
* @return threshold count
*/
function SLASH_COUNT() external view returns (uint256);
````
## File: src/interfaces/networkRestakeDelegator/INetworkRestakeDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface INetworkRestakeDecreaseHook is IDelegatorHook {
````
## File: src/interfaces/networkRestakeDelegator/INetworkRestakeRedistributeHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface INetworkRestakeRedistributeHook is IDelegatorHook {
````
## File: src/interfaces/networkRestakeDelegator/INetworkRestakeResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface INetworkRestakeResetHook is IDelegatorHook {
⋮----
/**
* @notice Get a period during which the slashing should occur to reset the operator's stake.
* @return threshold period
*/
function PERIOD() external view returns (uint48);
⋮----
/**
* @notice Get a number of slashes that should occur during the PERIOD to reset the operator's stake.
* @return threshold count
*/
function SLASH_COUNT() external view returns (uint256);
````
## File: src/interfaces/operatorSpecificDelegator/IOperatorSpecificDecreaseHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface IOperatorSpecificDecreaseHook is IDelegatorHook {
````
## File: src/interfaces/operatorSpecificDelegator/IOperatorSpecificResetHook.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
interface IOperatorSpecificResetHook is IDelegatorHook {
⋮----
/**
* @notice Get a period during which the slashing should occur to reset the operator's stake.
* @return threshold period
*/
function PERIOD() external view returns (uint48);
⋮----
/**
* @notice Get a number of slashes that should occur during the PERIOD to reset the operator's stake.
* @return threshold count
*/
function SLASH_COUNT() external view returns (uint256);
````
## File: test/fullRestakeDelegator/FullRestakeDecreaseHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IFullRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {FullRestakeDecreaseHook} from "../../src/contracts/fullRestakeDelegator/FullRestakeDecreaseHook.sol";
⋮----
contract FullRestakeDecreaseHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotFullRestakeDelegator(
````
## File: test/fullRestakeDelegator/FullRestakeResetHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {FullRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/FullRestakeDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IFullRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/IFullRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {FullRestakeResetHook} from "../../src/contracts/fullRestakeDelegator/FullRestakeResetHook.sol";
import {IFullRestakeResetHook} from "../../src/interfaces/fullRestakeDelegator/IFullRestakeResetHook.sol";
import {FakeDelegator} from "../mocks/FakeDelegator.sol";
⋮----
contract FullRestakeResetHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotFullRestakeDelegator(
⋮----
function test_SlashWithHookRevertNotVaultDelegator(
````
## File: test/integration/SymbioticHooksBindings.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticHooksImports.sol";
⋮----
import {Test} from "forge-std/Test.sol";
⋮----
contract SymbioticHooksBindings is Test {}
````
## File: test/integration/SymbioticHooksConstants.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticHooksImports.sol";
⋮----
function networkRestakeDecreaseHook() internal view returns (address) {
⋮----
// mainnet
⋮----
// holesky
⋮----
// sepolia
⋮----
// hoodi
⋮----
function networkRestakeRedistributeHook() internal view returns (address) {
⋮----
function fullRestakeDecreaseHook() internal view returns (address) {
⋮----
function operatorSpecificDecreaseHook() internal view returns (address) {
````
## File: test/integration/SymbioticHooksImports.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IFullRestakeDecreaseHook as ISymbioticFullRestakeDecreaseHook} from
"../../src/interfaces/fullRestakeDelegator/IFullRestakeDecreaseHook.sol";
import {IFullRestakeResetHook as ISymbioticFullRestakeResetHook} from
"../../src/interfaces/fullRestakeDelegator/IFullRestakeResetHook.sol";
import {INetworkRestakeDecreaseHook as ISymbioticNetworkRestakeDecreaseHook} from
"../../src/interfaces/networkRestakeDelegator/INetworkRestakeDecreaseHook.sol";
import {INetworkRestakeResetHook as ISymbioticNetworkRestakeResetHook} from
"../../src/interfaces/networkRestakeDelegator/INetworkRestakeResetHook.sol";
import {INetworkRestakeRedistributeHook as ISymbioticNetworkRestakeRedistributeHook} from
"../../src/interfaces/networkRestakeDelegator/INetworkRestakeRedistributeHook.sol";
import {IOperatorSpecificDecreaseHook as ISymbioticOperatorSpecificDecreaseHook} from
"../../src/interfaces/operatorSpecificDelegator/IOperatorSpecificDecreaseHook.sol";
import {IOperatorSpecificResetHook as ISymbioticOperatorSpecificResetHook} from
"../../src/interfaces/operatorSpecificDelegator/IOperatorSpecificResetHook.sol";
⋮----
interface SymbioticHooksImports {}
````
## File: test/integration/SymbioticHooksImportsContracts.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {FullRestakeDecreaseHook as SymbioticFullRestakeDecreaseHook} from
"../../src/contracts/fullRestakeDelegator/FullRestakeDecreaseHook.sol";
import {FullRestakeResetHook as SymbioticFullRestakeResetHook} from
"../../src/contracts/fullRestakeDelegator/FullRestakeResetHook.sol";
import {NetworkRestakeDecreaseHook as SymbioticNetworkRestakeDecreaseHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeDecreaseHook.sol";
import {NetworkRestakeResetHook as SymbioticNetworkRestakeResetHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeResetHook.sol";
import {NetworkRestakeRedistributeHook as SymbioticNetworkRestakeRedistributeHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeRedistributeHook.sol";
import {OperatorSpecificDecreaseHook as SymbioticOperatorSpecificDecreaseHook} from
"../../src/contracts/operatorSpecificDelegator/OperatorSpecificDecreaseHook.sol";
import {OperatorSpecificResetHook as SymbioticOperatorSpecificResetHook} from
"../../src/contracts/operatorSpecificDelegator/OperatorSpecificResetHook.sol";
⋮----
interface SymbioticHooksImportsContracts {}
````
## File: test/integration/SymbioticHooksInit.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreInit.sol";
⋮----
import "./SymbioticHooksImports.sol";
⋮----
import {SymbioticHooksConstants} from "./SymbioticHooksConstants.sol";
import {SymbioticHooksBindings} from "./SymbioticHooksBindings.sol";
⋮----
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
⋮----
contract SymbioticHooksInit is SymbioticCoreInit, SymbioticHooksBindings {
⋮----
// General config
⋮----
function setUp() public virtual override {
⋮----
// ------------------------------------------------------------ HOOKS-RELATED HELPERS ------------------------------------------------------------ //
⋮----
function _getNetworkRestakeDecreaseHook_SymbioticHooks(
⋮----
function _getNetworkRestakeRedistributeHook_SymbioticHooks(
⋮----
function _getNetworkRestakeResetHook_SymbioticHooks(
⋮----
function _getNetworkRestakeResetHook_SymbioticHooks() internal virtual returns (address) {
⋮----
function _getFullRestakeDecreaseHook_SymbioticHooks(
⋮----
function _getFullRestakeResetHook_SymbioticHooks(
⋮----
function _getFullRestakeResetHook_SymbioticHooks() internal virtual returns (address) {
⋮----
function _getOperatorSpecificDecreaseHook_SymbioticHooks(
⋮----
function _getOperatorSpecificResetHook_SymbioticHooks(
⋮----
function _getOperatorSpecificResetHook_SymbioticHooks() internal virtual returns (address) {
⋮----
function _getDecreaseHook_SymbioticHooks(
⋮----
function _getRedistributionHook_SymbioticHooks(
⋮----
function _getResetHook_SymbioticHooks(
⋮----
function _getHookRandom_SymbioticHooks(
````
## File: test/integration/SymbioticHooksIntegration.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "@symbioticfi/core/test/integration/SymbioticCoreIntegration.sol";
⋮----
import "./SymbioticHooksInit.sol";
⋮----
contract SymbioticHooksIntegration is SymbioticHooksInit, SymbioticCoreIntegration {
function setUp() public virtual override(SymbioticHooksInit, SymbioticCoreIntegration) {
⋮----
function _getVaultRandom_SymbioticCore(
⋮----
// New code
````
## File: test/integration/SymbioticHooksIntegrationExample.sol
````
// SPDX-License-Identifier: MIT
⋮----
import "./SymbioticHooksIntegration.sol";
⋮----
import {console2} from "forge-std/Test.sol";
⋮----
contract SymbioticHooksIntegrationExample is SymbioticHooksIntegration {
⋮----
uint256 public SELECT_OPERATOR_CHANCE = 1; // lower -> higher probability
⋮----
function setUp() public override {
⋮----
// vm.selectFork(vm.createFork(vm.rpcUrl("holesky")));
// SYMBIOTIC_INIT_BLOCK = 2_727_202;
// SYMBIOTIC_CORE_USE_EXISTING_DEPLOYMENT = true;
⋮----
function test_NetworkWithHooks() public {
⋮----
function _logAllocations(address vault, bytes32 subnetwork, address operator) internal {
````
## File: test/mocks/FakeDelegator.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {IDelegatorHook} from "@symbioticfi/core/src/interfaces/delegator/IDelegatorHook.sol";
⋮----
contract FakeDelegator {
⋮----
function onSlash(
````
## File: test/networkRestakeDelegator/NetworkRestakeDecreaseHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {NetworkRestakeDecreaseHook} from "../../src/contracts/networkRestakeDelegator/NetworkRestakeDecreaseHook.sol";
⋮----
contract NetworkRestakeDecreaseHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotNetworkRestakeDelegator(
````
## File: test/networkRestakeDelegator/NetworkRestakeRedistributeHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {NetworkRestakeRedistributeHook} from
"../../src/contracts/networkRestakeDelegator/NetworkRestakeRedistributeHook.sol";
⋮----
contract NetworkRestakeRedistributeHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotNetworkRestakeDelegator(
````
## File: test/networkRestakeDelegator/NetworkRestakeResetHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {NetworkRestakeDelegator} from "@symbioticfi/core/src/contracts/delegator/NetworkRestakeDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {INetworkRestakeDelegator} from "@symbioticfi/core/src/interfaces/delegator/INetworkRestakeDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {NetworkRestakeResetHook} from "../../src/contracts/networkRestakeDelegator/NetworkRestakeResetHook.sol";
import {INetworkRestakeResetHook} from "../../src/interfaces/networkRestakeDelegator/INetworkRestakeResetHook.sol";
import {FakeDelegator} from "../mocks/FakeDelegator.sol";
⋮----
contract NetworkRestakeResetHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotNetworkRestakeDelegator(
⋮----
function test_SlashWithHookRevertNotVaultDelegator(
````
## File: test/operatorSpecificDelegator/OperatorSpecificDecreaseHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IOperatorSpecificDelegator} from "@symbioticfi/core/src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {OperatorSpecificDecreaseHook} from
"../../src/contracts/operatorSpecificDelegator/OperatorSpecificDecreaseHook.sol";
⋮----
contract OperatorSpecificDecreaseHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotOperatorSpecificDelegator(
⋮----
function _setNetworkLimitOperator(
````
## File: test/operatorSpecificDelegator/OperatorSpecificResetHook.t.sol
````
// SPDX-License-Identifier: MIT
⋮----
import {POCBaseTest} from "@symbioticfi/core/test/POCBase.t.sol";
import {Vault} from "@symbioticfi/core/src/contracts/vault/Vault.sol";
import {OperatorSpecificDelegator} from "@symbioticfi/core/src/contracts/delegator/OperatorSpecificDelegator.sol";
import {Slasher} from "@symbioticfi/core/src/contracts/slasher/Slasher.sol";
import {IBaseSlasher} from "@symbioticfi/core/src/interfaces/slasher/IBaseSlasher.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {IBaseDelegator} from "@symbioticfi/core/src/interfaces/delegator/IBaseDelegator.sol";
import {IOperatorSpecificDelegator} from "@symbioticfi/core/src/interfaces/delegator/IOperatorSpecificDelegator.sol";
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVaultConfigurator} from "@symbioticfi/core/src/interfaces/IVaultConfigurator.sol";
⋮----
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
⋮----
import {OperatorSpecificResetHook} from "../../src/contracts/operatorSpecificDelegator/OperatorSpecificResetHook.sol";
import {IOperatorSpecificResetHook} from "../../src/interfaces/operatorSpecificDelegator/IOperatorSpecificResetHook.sol";
import {FakeDelegator} from "../mocks/FakeDelegator.sol";
⋮----
contract OperatorSpecificResetHookTest is POCBaseTest {
⋮----
function setUp() public override {
⋮----
function test_SlashWithHook(
⋮----
function test_SlashWithHookRevertNotOperatorSpecificDelegator(
⋮----
function test_SlashWithHookRevertNotVaultDelegator(
⋮----
function _setNetworkLimitOperator(
````
## File: .env.example
````
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
````
## File: .gitignore
````
# Compiler files
cache/
out/**/
!out/FullRestakeDecreaseHook.sol/
!out/FullRestakeResetHook.sol/
!out/NetworkRestakeDecreaseHook.sol/
!out/NetworkRestakeRedistributeHook.sol/
!out/NetworkRestakeResetHook.sol/
!out/OperatorSpecificDecreaseHook.sol/
!out/OperatorSpecificResetHook.sol/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/*/11155111/
/broadcast/**/dry-run/
# Docs
docs/
# Dotenv file
.env
# Other files
.gas-snapshot
lcov.info
node_modules
package-lock.json
````
## File: .gitmodules
````
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/core"]
path = lib/core
url = https://github.com/symbioticfi/core
````
## File: foundry.toml
````toml
[profile.default]
evm_version = "cancun"
solc = "0.8.25"
optimizer = true
optimizer_runs = 200
via_ir = true
src = "src"
out = "out"
libs = ["lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
gas_reports = ["*"]
gas_limit = "18446744073709551615"
[rpc_endpoints]
mainnet = "${ETH_RPC_URL}"
holesky = "${ETH_RPC_URL_HOLESKY}"
[fmt]
bracket_spacing = false
int_types = "long"
line_length = 120
multiline_func_header = "params_first"
number_underscore = "thousands"
quote_style = "double"
tab_width = 4
[fuzz]
runs = 4096
max_test_rejects = 262144
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
````
## File: LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: package.json
````json
{
"name": "@symbioticfi/hooks",
"version": "1.0.0",
"description": "Symbiotic Hooks repository contains several basic on-slash hook implementations for different delegator types.",
"homepage": "https://symbiotic.fi/",
"bugs": "https://github.com/symbioticfi/hooks/issues",
"license": "MIT",
"author": "Symbiotic Team",
"files": [
"src/**/*",
"test/mocks/**/*",
"out/**/*.json"
],
"repository": {
"type": "git",
"url": "https://github.com/symbioticfi/hooks.git"
},
"keywords": [
"solidity",
"ethereum",
"smart",
"contracts",
"security"
],
"dependencies": {
"@openzeppelin/contracts": "5.1.0",
"@openzeppelin/contracts-upgradeable": "5.1.0",
"@symbioticfi/core": "1.0.0-devnet.9"
}
}
````
## File: README.md
````markdown
**[Symbiotic Protocol](https://symbiotic.fi) is an extremely flexible and permissionless shared security system.**
This repository contains default on-slash hooks.
[](https://deepwiki.com/symbioticfi/hooks)
## Technical Documentation
Can be found [here](./specs).
## Security
Security audits can be found [here](./audits).
## Usage
### Env
Create `.env` file using a template:
```
ETH_RPC_URL=
ETH_RPC_URL_HOLESKY=
ETHERSCAN_API_KEY=
```
\* ETH_RPC_URL is optional. \* ETH_RPC_URL_HOLESKY is optional. \* ETHERSCAN_API_KEY is optional.
### Build
```shell
forge build
```
### Test
```shell
forge test
```
### Format
```shell
forge fmt
```
### Gas Snapshots
```shell
forge snapshot
```
````
## File: remappings.txt
````
forge-std/=lib/forge-std/src/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@symbioticfi/core/=lib/core/
````
---
## Python CLI
This file is a merged representation of the entire codebase, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).
# File Summary
## Purpose
This file contains a packed representation of the entire repository's contents.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
## File Format
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A header with the file path (## File: path/to/file)
b. The full contents of the file in a code block
## Usage Guidelines
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
## Notes
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)
# Directory Structure
```
abi/
BurnerRouterABI.json
BurnerRouterFactoryABI.json
DefaultCollateralMigratorABI.json
DefaultOperatorRewardsABI.json
DefaultOperatorRewardsFactoryABI.json
DefaultStakerRewardsABI.json
DefaultStakerRewardsFactoryABI.json
DelegatorFactoryABI.json
ETHx_BurnerABI.json
FullRestakeDecreaseHookABI.json
FullRestakeDelegatorABI.json
mETH_BurnerABI.json
NetworkMiddlewareServiceABI.json
NetworkRegistryABI.json
NetworkRestakeDecreaseHookABI.json
NetworkRestakeDelegatorABI.json
NetworkRestakeRedistributeHookABI.json
OperatorNetworkOptInServiceABI.json
OperatorNetworkSpecificDelegatorABI.json
OperatorRegistryABI.json
OperatorSpecificDecreaseHookABI.json
OperatorSpecificDelegatorABI.json
OperatorVaultOptInServiceABI.json
rETH_BurnerABI.json
sfrxETH_BurnerABI.json
SlasherABI.json
SlasherFactoryABI.json
swETH_BurnerABI.json
VaultABI.json
VaultConfiguratorABI.json
VaultFactoryABI.json
VaultTokenizedABI.json
VetoSlasherABI.json
wstETH_BurnerABI.json
LICENSE
README.md
requirements.txt
symb.py
```
# Files
## File: abi/BurnerRouterABI.json
````json
[
{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "DuplicateNetworkReceiver", "type": "error" },
{ "inputs": [], "name": "DuplicateOperatorNetworkReceiver", "type": "error" },
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "InsufficientBalance", "type": "error" },
{ "inputs": [], "name": "InvalidCollateral", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidReceiver", "type": "error" },
{ "inputs": [], "name": "InvalidReceiverSetEpochsDelay", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotReady", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{ "anonymous": false, "inputs": [], "name": "AcceptDelay", "type": "event" },
{
"anonymous": false,
"inputs": [],
"name": "AcceptGlobalReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
}
],
"name": "AcceptNetworkReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "AcceptOperatorNetworkReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint48",
"name": "delay",
"type": "uint48"
}
],
"name": "SetDelay",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "SetGlobalReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "SetNetworkReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "SetOperatorNetworkReceiver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TriggerTransfer",
"type": "event"
},
{
"inputs": [],
"name": "acceptDelay",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "acceptGlobalReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "acceptNetworkReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "acceptOperatorNetworkReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "balanceOf",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "collateral",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delay",
"outputs": [
{ "internalType": "uint48", "name": "value", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "globalReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "owner", "type": "address" },
{
"internalType": "address",
"name": "collateral",
"type": "address"
},
{ "internalType": "uint48", "name": "delay", "type": "uint48" },
{
"internalType": "address",
"name": "globalReceiver",
"type": "address"
},
{
"components": [
{
"internalType": "address",
"name": "network",
"type": "address"
},
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"internalType": "struct IBurnerRouter.NetworkReceiver[]",
"name": "networkReceivers",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "network",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"internalType": "struct IBurnerRouter.OperatorNetworkReceiver[]",
"name": "operatorNetworkReceivers",
"type": "tuple[]"
}
],
"internalType": "struct IBurnerRouter.InitParams",
"name": "params",
"type": "tuple"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "lastBalance",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "networkReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "", "type": "uint256" },
{ "internalType": "uint48", "name": "", "type": "uint48" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "operatorNetworkReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingDelay",
"outputs": [
{ "internalType": "uint48", "name": "value", "type": "uint48" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingGlobalReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "pendingNetworkReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "pendingOperatorNetworkReceiver",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "newDelay", "type": "uint48" }
],
"name": "setDelay",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "setGlobalReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "setNetworkReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "setOperatorNetworkReceiver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "triggerTransfer",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/BurnerRouterFactoryABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "burnerRouterImplementation",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "owner", "type": "address" },
{
"internalType": "address",
"name": "collateral",
"type": "address"
},
{ "internalType": "uint48", "name": "delay", "type": "uint48" },
{
"internalType": "address",
"name": "globalReceiver",
"type": "address"
},
{
"components": [
{
"internalType": "address",
"name": "network",
"type": "address"
},
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"internalType": "struct IBurnerRouter.NetworkReceiver[]",
"name": "networkReceivers",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "network",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"internalType": "struct IBurnerRouter.OperatorNetworkReceiver[]",
"name": "operatorNetworkReceivers",
"type": "tuple[]"
}
],
"internalType": "struct IBurnerRouter.InitParams",
"name": "params",
"type": "tuple"
}
],
"name": "create",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/DefaultCollateralMigratorABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" },
{ "internalType": "address", "name": "vault", "type": "address" },
{ "internalType": "address", "name": "onBehalfOf", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "migrate",
"outputs": [
{ "internalType": "uint256", "name": "", "type": "uint256" },
{ "internalType": "uint256", "name": "", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/DefaultOperatorRewardsABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "networkMiddlewareService",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "InsufficientBalance", "type": "error" },
{ "inputs": [], "name": "InsufficientTotalClaimable", "type": "error" },
{ "inputs": [], "name": "InsufficientTransfer", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidProof", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetworkMiddleware", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{ "inputs": [], "name": "RootNotSet", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "root",
"type": "bytes32"
}
],
"name": "DistributeRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"inputs": [],
"name": "NETWORK_MIDDLEWARE_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "balance",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{
"internalType": "uint256",
"name": "totalClaimable",
"type": "uint256"
},
{ "internalType": "bytes32[]", "name": "proof", "type": "bytes32[]" }
],
"name": "claimRewards",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "claimed",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{ "internalType": "bytes32", "name": "root_", "type": "bytes32" }
],
"name": "distributeRewards",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "root",
"outputs": [
{ "internalType": "bytes32", "name": "value", "type": "bytes32" }
],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/DefaultOperatorRewardsFactoryABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "operatorRewardsImplementation",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"inputs": [],
"name": "create",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/DefaultStakerRewardsABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "networkMiddlewareService",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "HighAdminFee", "type": "error" },
{ "inputs": [], "name": "InsufficientAdminFee", "type": "error" },
{ "inputs": [], "name": "InsufficientReward", "type": "error" },
{ "inputs": [], "name": "InvalidAdminFee", "type": "error" },
{ "inputs": [], "name": "InvalidHintsLength", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidRecipient", "type": "error" },
{ "inputs": [], "name": "InvalidRewardTimestamp", "type": "error" },
{ "inputs": [], "name": "MathOverflowedMulDiv", "type": "error" },
{ "inputs": [], "name": "MissingRoles", "type": "error" },
{ "inputs": [], "name": "NoRewardsToClaim", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotNetworkMiddleware", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimAdminFee",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "firstRewardIndex",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "numRewards",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "DistributeRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "adminFee",
"type": "uint256"
}
],
"name": "SetAdminFee",
"type": "event"
},
{
"inputs": [],
"name": "ADMIN_FEE_BASE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "ADMIN_FEE_CLAIM_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "ADMIN_FEE_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_MIDDLEWARE_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "adminFee",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "claimAdminFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "claimRewards",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "claimable",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "claimableAdminFee",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "distributeRewards",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "vault", "type": "address" },
{ "internalType": "uint256", "name": "adminFee", "type": "uint256" },
{
"internalType": "address",
"name": "defaultAdminRoleHolder",
"type": "address"
},
{
"internalType": "address",
"name": "adminFeeClaimRoleHolder",
"type": "address"
},
{
"internalType": "address",
"name": "adminFeeSetRoleHolder",
"type": "address"
}
],
"internalType": "struct IDefaultStakerRewards.InitParams",
"name": "params",
"type": "tuple"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "lastUnclaimedReward",
"outputs": [
{ "internalType": "uint256", "name": "rewardIndex", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
],
"name": "multicall",
"outputs": [
{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "address", "name": "network", "type": "address" },
{ "internalType": "uint256", "name": "", "type": "uint256" }
],
"name": "rewards",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "rewardsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "adminFee_", "type": "uint256" }
],
"name": "setAdminFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/DefaultStakerRewardsFactoryABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "stakerRewardsImplementation",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "vault", "type": "address" },
{ "internalType": "uint256", "name": "adminFee", "type": "uint256" },
{
"internalType": "address",
"name": "defaultAdminRoleHolder",
"type": "address"
},
{
"internalType": "address",
"name": "adminFeeClaimRoleHolder",
"type": "address"
},
{
"internalType": "address",
"name": "adminFeeSetRoleHolder",
"type": "address"
}
],
"internalType": "struct IDefaultStakerRewards.InitParams",
"name": "params",
"type": "tuple"
}
],
"name": "create",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/DelegatorFactoryABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "owner_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadyBlacklisted", "type": "error" },
{ "inputs": [], "name": "AlreadyWhitelisted", "type": "error" },
{ "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{ "inputs": [], "name": "InvalidImplementation", "type": "error" },
{ "inputs": [], "name": "InvalidType", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint64",
"name": "type_",
"type": "uint64"
}
],
"name": "Blacklist",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Whitelist",
"type": "event"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "blacklist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "blacklisted",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "type_", "type": "uint64" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "create",
"outputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "implementation",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalTypes",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation_",
"type": "address"
}
],
"name": "whitelist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/ETHx_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" },
{ "internalType": "address", "name": "staderConfig", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "InvalidETHxMaximumWithdrawal", "type": "error" },
{ "inputs": [], "name": "InvalidRequestId", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerWithdrawal",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "STADER_CONFIG",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "STAKE_POOLS_MANAGER",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "USER_WITHDRAW_MANAGER",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
],
"name": "multicall",
"outputs": [
{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" },
{ "internalType": "uint256", "name": "maxRequestIds", "type": "uint256" }
],
"name": "requestIds",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "requestIdsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "maxWithdrawalAmount",
"type": "uint256"
}
],
"name": "triggerWithdrawal",
"outputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: abi/FullRestakeDecreaseHookABI.json
````json
[
{ "inputs": [], "name": "NotFullRestakeDelegator", "type": "error" },
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" },
{ "internalType": "uint48", "name": "", "type": "uint48" },
{ "internalType": "bytes", "name": "", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/FullRestakeDelegatorABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "operatorVaultOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "operatorNetworkOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "DuplicateRoleHolder", "type": "error" },
{ "inputs": [], "name": "ExceedsMaxNetworkLimit", "type": "error" },
{ "inputs": [], "name": "InsufficientHookGas", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "MissingRoleHolders", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{ "inputs": [], "name": "ZeroAddressRoleHolder", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "hook",
"type": "address"
}
],
"name": "SetHook",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetMaxNetworkLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetNetworkLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetOperatorNetworkLimit",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_VAULT_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VERSION",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "maxNetworkLimit",
"outputs": [
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "networkLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "networkLimitAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "operatorNetworkLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "operatorNetworkLimitAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "hook_", "type": "address" }
],
"name": "setHook",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint96", "name": "identifier", "type": "uint96" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setMaxNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setOperatorNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "stake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "stakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/mETH_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "InvalidRequestId", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerWithdrawal",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "STAKING",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" },
{ "internalType": "uint256", "name": "maxRequestIds", "type": "uint256" }
],
"name": "requestIds",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "requestIdsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "triggerWithdrawal",
"outputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: abi/NetworkMiddlewareServiceABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "network",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "middleware",
"type": "address"
}
],
"name": "SetMiddleware",
"type": "event"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "network", "type": "address" }
],
"name": "middleware",
"outputs": [
{ "internalType": "address", "name": "value", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "middleware_", "type": "address" }
],
"name": "setMiddleware",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/NetworkRegistryABI.json
````json
[
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{ "inputs": [], "name": "NetworkAlreadyRegistered", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "registerNetwork",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/NetworkRestakeDecreaseHookABI.json
````json
[
{ "inputs": [], "name": "NotNetworkRestakeDelegator", "type": "error" },
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/NetworkRestakeDelegatorABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "operatorVaultOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "operatorNetworkOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "DuplicateRoleHolder", "type": "error" },
{ "inputs": [], "name": "ExceedsMaxNetworkLimit", "type": "error" },
{ "inputs": [], "name": "InsufficientHookGas", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "MathOverflowedMulDiv", "type": "error" },
{ "inputs": [], "name": "MissingRoleHolders", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{ "inputs": [], "name": "ZeroAddressRoleHolder", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "hook",
"type": "address"
}
],
"name": "SetHook",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetMaxNetworkLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetNetworkLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"name": "SetOperatorNetworkShares",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_SHARES_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_VAULT_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VERSION",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "maxNetworkLimit",
"outputs": [
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "networkLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "networkLimitAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "operatorNetworkShares",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "operatorNetworkSharesAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "hook_", "type": "address" }
],
"name": "setHook",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint96", "name": "identifier", "type": "uint96" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setMaxNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "shares", "type": "uint256" }
],
"name": "setOperatorNetworkShares",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "stake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "stakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "totalOperatorNetworkShares",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "totalOperatorNetworkSharesAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/NetworkRestakeRedistributeHookABI.json
````json
[
{ "inputs": [], "name": "NotNetworkRestakeDelegator", "type": "error" },
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/OperatorNetworkOptInServiceABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "whoRegistry", "type": "address" },
{ "internalType": "address", "name": "whereRegistry", "type": "address" },
{ "internalType": "string", "name": "name", "type": "string" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadyOptedIn", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "ExpiredSignature", "type": "error" },
{ "inputs": [], "name": "InvalidShortString", "type": "error" },
{ "inputs": [], "name": "InvalidSignature", "type": "error" },
{ "inputs": [], "name": "NotOptedIn", "type": "error" },
{ "inputs": [], "name": "NotWhereEntity", "type": "error" },
{ "inputs": [], "name": "NotWho", "type": "error" },
{ "inputs": [], "name": "OptOutCooldown", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [{ "internalType": "string", "name": "str", "type": "string" }],
"name": "StringTooLong",
"type": "error"
},
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "IncreaseNonce",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "OptIn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "OptOut",
"type": "event"
},
{
"inputs": [],
"name": "WHERE_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "WHO_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{ "internalType": "bytes1", "name": "fields", "type": "bytes1" },
{ "internalType": "string", "name": "name", "type": "string" },
{ "internalType": "string", "name": "version", "type": "string" },
{ "internalType": "uint256", "name": "chainId", "type": "uint256" },
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{ "internalType": "bytes32", "name": "salt", "type": "bytes32" },
{ "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "increaseNonce",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "isOptedIn",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "isOptedInAt",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "nonces",
"outputs": [
{ "internalType": "uint256", "name": "nonce", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "optIn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "deadline", "type": "uint48" },
{ "internalType": "bytes", "name": "signature", "type": "bytes" }
],
"name": "optIn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "deadline", "type": "uint48" },
{ "internalType": "bytes", "name": "signature", "type": "bytes" }
],
"name": "optOut",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "optOut",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/OperatorNetworkSpecificDelegatorABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "operatorRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "operatorVaultOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "operatorNetworkOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "InsufficientHookGas", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidNetwork", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotOperator", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "hook",
"type": "address"
}
],
"name": "SetHook",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetMaxNetworkLimit",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_VAULT_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VERSION",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "maxNetworkLimit",
"outputs": [
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "maxNetworkLimitAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "network",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "operator",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "hook_", "type": "address" }
],
"name": "setHook",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint96", "name": "identifier", "type": "uint96" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setMaxNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "stake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "stakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/OperatorRegistryABI.json
````json
[
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{ "inputs": [], "name": "OperatorAlreadyRegistered", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "registerOperator",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/OperatorSpecificDecreaseHookABI.json
````json
[
{ "inputs": [], "name": "NotOperatorSpecificDelegator", "type": "error" },
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" },
{ "internalType": "uint48", "name": "", "type": "uint48" },
{ "internalType": "bytes", "name": "", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/OperatorSpecificDelegatorABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "operatorRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "operatorVaultOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "operatorNetworkOptInService",
"type": "address"
},
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "DuplicateRoleHolder", "type": "error" },
{ "inputs": [], "name": "ExceedsMaxNetworkLimit", "type": "error" },
{ "inputs": [], "name": "InsufficientHookGas", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "MissingRoleHolders", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotOperator", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{ "inputs": [], "name": "ZeroAddressRoleHolder", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "hook",
"type": "address"
}
],
"name": "SetHook",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetMaxNetworkLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SetNetworkLimit",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "HOOK_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_NETWORK_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "OPERATOR_VAULT_OPT_IN_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VERSION",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "maxNetworkLimit",
"outputs": [
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" }
],
"name": "networkLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "networkLimitAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "onSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "operator",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "hook_", "type": "address" }
],
"name": "setHook",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint96", "name": "identifier", "type": "uint96" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setMaxNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "setNetworkLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "stake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "stakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/OperatorVaultOptInServiceABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "whoRegistry", "type": "address" },
{ "internalType": "address", "name": "whereRegistry", "type": "address" },
{ "internalType": "string", "name": "name", "type": "string" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadyOptedIn", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "ExpiredSignature", "type": "error" },
{ "inputs": [], "name": "InvalidShortString", "type": "error" },
{ "inputs": [], "name": "InvalidSignature", "type": "error" },
{ "inputs": [], "name": "NotOptedIn", "type": "error" },
{ "inputs": [], "name": "NotWhereEntity", "type": "error" },
{ "inputs": [], "name": "NotWho", "type": "error" },
{ "inputs": [], "name": "OptOutCooldown", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [{ "internalType": "string", "name": "str", "type": "string" }],
"name": "StringTooLong",
"type": "error"
},
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "IncreaseNonce",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "OptIn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "where",
"type": "address"
}
],
"name": "OptOut",
"type": "event"
},
{
"inputs": [],
"name": "WHERE_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "WHO_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{ "internalType": "bytes1", "name": "fields", "type": "bytes1" },
{ "internalType": "string", "name": "name", "type": "string" },
{ "internalType": "string", "name": "version", "type": "string" },
{ "internalType": "uint256", "name": "chainId", "type": "uint256" },
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{ "internalType": "bytes32", "name": "salt", "type": "bytes32" },
{ "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "increaseNonce",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "isOptedIn",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "isOptedInAt",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "nonces",
"outputs": [
{ "internalType": "uint256", "name": "nonce", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "optIn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "deadline", "type": "uint48" },
{ "internalType": "bytes", "name": "signature", "type": "bytes" }
],
"name": "optIn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "who", "type": "address" },
{ "internalType": "address", "name": "where", "type": "address" },
{ "internalType": "uint48", "name": "deadline", "type": "uint48" },
{ "internalType": "bytes", "name": "signature", "type": "bytes" }
],
"name": "optOut",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "where", "type": "address" }
],
"name": "optOut",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/rETH_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "assetAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: abi/sfrxETH_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" },
{
"internalType": "address",
"name": "fraxEtherRedemptionQueue",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "InvalidRequestId", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerWithdrawal",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FRAX_ETHER_REDEMPTION_QUEUE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "uint256", "name": "", "type": "uint256" },
{ "internalType": "bytes", "name": "", "type": "bytes" }
],
"name": "onERC721Received",
"outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" },
{ "internalType": "uint256", "name": "maxRequestIds", "type": "uint256" }
],
"name": "requestIds",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "requestIdsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "triggerWithdrawal",
"outputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: abi/SlasherABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "networkMiddlewareService",
"type": "address"
},
{
"internalType": "address",
"name": "slasherFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "InsufficientBurnerGas", "type": "error" },
{ "inputs": [], "name": "InsufficientSlash", "type": "error" },
{ "inputs": [], "name": "InvalidCaptureTimestamp", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "NoBurner", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetworkMiddleware", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slashedAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
}
],
"name": "Slash",
"type": "event"
},
{
"inputs": [],
"name": "BURNER_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "BURNER_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_MIDDLEWARE_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "cumulativeSlash",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "cumulativeSlashAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "isBurnerHook",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "latestSlashedCaptureTimestamp",
"outputs": [
{ "internalType": "uint48", "name": "value", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "slash",
"outputs": [
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "slashableStake",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/SlasherFactoryABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "owner_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadyBlacklisted", "type": "error" },
{ "inputs": [], "name": "AlreadyWhitelisted", "type": "error" },
{ "inputs": [], "name": "ERC1167FailedCreateClone", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{ "inputs": [], "name": "InvalidImplementation", "type": "error" },
{ "inputs": [], "name": "InvalidType", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint64",
"name": "type_",
"type": "uint64"
}
],
"name": "Blacklist",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Whitelist",
"type": "event"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "blacklist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "blacklisted",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "type_", "type": "uint64" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "create",
"outputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint64", "name": "type_", "type": "uint64" }],
"name": "implementation",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalTypes",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation_",
"type": "address"
}
],
"name": "whitelist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/swETH_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" },
{ "internalType": "address", "name": "swEXIT", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "InsufficientWithdrawal", "type": "error" },
{ "inputs": [], "name": "InvalidRequestId", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "firstRequestId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "lastRequestId",
"type": "uint256"
}
],
"name": "TriggerWithdrawal",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SWEXIT",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "uint256", "name": "", "type": "uint256" },
{ "internalType": "bytes", "name": "", "type": "bytes" }
],
"name": "onERC721Received",
"outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" },
{ "internalType": "uint256", "name": "maxRequestIds", "type": "uint256" }
],
"name": "requestIds",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "requestIdsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "maxRequests", "type": "uint256" }
],
"name": "triggerWithdrawal",
"outputs": [
{
"internalType": "uint256",
"name": "firstRequestId",
"type": "uint256"
},
{ "internalType": "uint256", "name": "lastRequestId", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: abi/VaultABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{
"internalType": "address",
"name": "slasherFactory",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "AlreadyClaimed", "type": "error" },
{ "inputs": [], "name": "AlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "DelegatorAlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "DepositLimitReached", "type": "error" },
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "InsufficientClaim", "type": "error" },
{ "inputs": [], "name": "InsufficientDeposit", "type": "error" },
{ "inputs": [], "name": "InsufficientRedemption", "type": "error" },
{ "inputs": [], "name": "InsufficientWithdrawal", "type": "error" },
{ "inputs": [], "name": "InvalidAccount", "type": "error" },
{ "inputs": [], "name": "InvalidCaptureEpoch", "type": "error" },
{ "inputs": [], "name": "InvalidClaimer", "type": "error" },
{ "inputs": [], "name": "InvalidCollateral", "type": "error" },
{ "inputs": [], "name": "InvalidDelegator", "type": "error" },
{ "inputs": [], "name": "InvalidEpoch", "type": "error" },
{ "inputs": [], "name": "InvalidEpochDuration", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidLengthEpochs", "type": "error" },
{ "inputs": [], "name": "InvalidOnBehalfOf", "type": "error" },
{ "inputs": [], "name": "InvalidRecipient", "type": "error" },
{ "inputs": [], "name": "InvalidSlasher", "type": "error" },
{ "inputs": [], "name": "InvalidTimestamp", "type": "error" },
{ "inputs": [], "name": "MathOverflowedMulDiv", "type": "error" },
{ "inputs": [], "name": "MissingRoles", "type": "error" },
{ "inputs": [], "name": "NoPreviousEpoch", "type": "error" },
{ "inputs": [], "name": "NotDelegator", "type": "error" },
{ "inputs": [], "name": "NotFactory", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotWhitelistedDepositor", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{ "inputs": [], "name": "SlasherAlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "TooMuchRedeem", "type": "error" },
{ "inputs": [], "name": "TooMuchWithdraw", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "epoch",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Claim",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "epochs",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimBatch",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "depositor",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "onBehalfOf",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slashedAmount",
"type": "uint256"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "delegator",
"type": "address"
}
],
"name": "SetDelegator",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "limit",
"type": "uint256"
}
],
"name": "SetDepositLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetDepositWhitelist",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetDepositorWhitelistStatus",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetIsDepositLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "slasher",
"type": "address"
}
],
"name": "SetSlasher",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "burnedShares",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "mintedShares",
"type": "uint256"
}
],
"name": "Withdraw",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DELEGATOR_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSITOR_WHITELIST_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSIT_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSIT_WHITELIST_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "IS_DEPOSIT_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SLASHER_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "activeBalanceOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "activeBalanceOfAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "activeShares",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeSharesAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "activeSharesOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeSharesOfAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "activeStake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeStakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "burner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "claim",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256[]", "name": "epochs", "type": "uint256[]" }
],
"name": "claimBatch",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "collateral",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentEpoch",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delegator",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "onBehalfOf", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "deposit",
"outputs": [
{
"internalType": "uint256",
"name": "depositedAmount",
"type": "uint256"
},
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "depositLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "depositWhitelist",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"name": "epochAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "epochDuration",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "epochDurationInit",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "initialVersion", "type": "uint64" },
{ "internalType": "address", "name": "owner_", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "isDelegatorInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isDepositLimit",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "isDepositorWhitelisted",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isSlasherInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "isWithdrawalsClaimed",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "newVersion", "type": "uint64" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "migrate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "nextEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{ "internalType": "uint48", "name": "captureTimestamp", "type": "uint48" }
],
"name": "onSlash",
"outputs": [
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "previousEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "claimer", "type": "address" },
{ "internalType": "uint256", "name": "shares", "type": "uint256" }
],
"name": "redeem",
"outputs": [
{
"internalType": "uint256",
"name": "withdrawnAssets",
"type": "uint256"
},
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "delegator_", "type": "address" }
],
"name": "setDelegator",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "limit", "type": "uint256" }
],
"name": "setDepositLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "bool", "name": "status", "type": "bool" }],
"name": "setDepositWhitelist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bool", "name": "status", "type": "bool" }
],
"name": "setDepositorWhitelistStatus",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "bool", "name": "status", "type": "bool" }],
"name": "setIsDepositLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "slasher_", "type": "address" }
],
"name": "setSlasher",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "slashableBalanceOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "slasher",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalStake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "claimer", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "withdraw",
"outputs": [
{ "internalType": "uint256", "name": "burnedShares", "type": "uint256" },
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "withdrawalShares",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "withdrawalSharesOf",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "withdrawals",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "withdrawalsOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/VaultConfiguratorABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{ "internalType": "address", "name": "slasherFactory", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "DELEGATOR_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SLASHER_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "uint64", "name": "version", "type": "uint64" },
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "bytes", "name": "vaultParams", "type": "bytes" },
{
"internalType": "uint64",
"name": "delegatorIndex",
"type": "uint64"
},
{
"internalType": "bytes",
"name": "delegatorParams",
"type": "bytes"
},
{ "internalType": "bool", "name": "withSlasher", "type": "bool" },
{
"internalType": "uint64",
"name": "slasherIndex",
"type": "uint64"
},
{ "internalType": "bytes", "name": "slasherParams", "type": "bytes" }
],
"internalType": "struct IVaultConfigurator.InitParams",
"name": "params",
"type": "tuple"
}
],
"name": "create",
"outputs": [
{ "internalType": "address", "name": "vault", "type": "address" },
{ "internalType": "address", "name": "delegator", "type": "address" },
{ "internalType": "address", "name": "slasher", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/VaultFactoryABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "owner_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadyBlacklisted", "type": "error" },
{ "inputs": [], "name": "AlreadyWhitelisted", "type": "error" },
{ "inputs": [], "name": "EntityNotExist", "type": "error" },
{ "inputs": [], "name": "InvalidImplementation", "type": "error" },
{ "inputs": [], "name": "InvalidVersion", "type": "error" },
{ "inputs": [], "name": "NotOwner", "type": "error" },
{ "inputs": [], "name": "OldVersion", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
}
],
"name": "AddEntity",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Blacklist",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "entity",
"type": "address"
},
{
"indexed": false,
"internalType": "uint64",
"name": "newVersion",
"type": "uint64"
}
],
"name": "Migrate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Whitelist",
"type": "event"
},
{
"inputs": [
{ "internalType": "uint64", "name": "version", "type": "uint64" }
],
"name": "blacklist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "version", "type": "uint64" }
],
"name": "blacklisted",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "version", "type": "uint64" },
{ "internalType": "address", "name": "owner_", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "create",
"outputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" }
],
"name": "entity",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "version", "type": "uint64" }
],
"name": "implementation",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" }
],
"name": "isEntity",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "lastVersion",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "entity_", "type": "address" },
{ "internalType": "uint64", "name": "newVersion", "type": "uint64" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "migrate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalEntities",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation_",
"type": "address"
}
],
"name": "whitelist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/VaultTokenizedABI.json
````json
[
{
"inputs": [
{
"internalType": "address",
"name": "delegatorFactory",
"type": "address"
},
{
"internalType": "address",
"name": "slasherFactory",
"type": "address"
},
{ "internalType": "address", "name": "vaultFactory", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AccessControlBadConfirmation", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bytes32", "name": "neededRole", "type": "bytes32" }
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" }
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "AddressInsufficientBalance",
"type": "error"
},
{ "inputs": [], "name": "AlreadyClaimed", "type": "error" },
{ "inputs": [], "name": "AlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "DelegatorAlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "DepositLimitReached", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "spender", "type": "address" },
{ "internalType": "uint256", "name": "allowance", "type": "uint256" },
{ "internalType": "uint256", "name": "needed", "type": "uint256" }
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "sender", "type": "address" },
{ "internalType": "uint256", "name": "balance", "type": "uint256" },
{ "internalType": "uint256", "name": "needed", "type": "uint256" }
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "approver", "type": "address" }
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "receiver", "type": "address" }
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "sender", "type": "address" }
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "spender", "type": "address" }
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{ "inputs": [], "name": "FailedInnerCall", "type": "error" },
{ "inputs": [], "name": "InsufficientClaim", "type": "error" },
{ "inputs": [], "name": "InsufficientDeposit", "type": "error" },
{ "inputs": [], "name": "InsufficientRedemption", "type": "error" },
{ "inputs": [], "name": "InsufficientWithdrawal", "type": "error" },
{ "inputs": [], "name": "InvalidAccount", "type": "error" },
{ "inputs": [], "name": "InvalidCaptureEpoch", "type": "error" },
{ "inputs": [], "name": "InvalidClaimer", "type": "error" },
{ "inputs": [], "name": "InvalidCollateral", "type": "error" },
{ "inputs": [], "name": "InvalidDelegator", "type": "error" },
{ "inputs": [], "name": "InvalidEpoch", "type": "error" },
{ "inputs": [], "name": "InvalidEpochDuration", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidLengthEpochs", "type": "error" },
{ "inputs": [], "name": "InvalidOnBehalfOf", "type": "error" },
{ "inputs": [], "name": "InvalidRecipient", "type": "error" },
{ "inputs": [], "name": "InvalidSlasher", "type": "error" },
{ "inputs": [], "name": "InvalidTimestamp", "type": "error" },
{ "inputs": [], "name": "MathOverflowedMulDiv", "type": "error" },
{ "inputs": [], "name": "MissingRoles", "type": "error" },
{ "inputs": [], "name": "NoPreviousEpoch", "type": "error" },
{ "inputs": [], "name": "NotDelegator", "type": "error" },
{ "inputs": [], "name": "NotFactory", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotSlasher", "type": "error" },
{ "inputs": [], "name": "NotWhitelistedDepositor", "type": "error" },
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" }
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{ "inputs": [], "name": "SlasherAlreadyInitialized", "type": "error" },
{ "inputs": [], "name": "TooMuchRedeem", "type": "error" },
{ "inputs": [], "name": "TooMuchWithdraw", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "epoch",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Claim",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "epochs",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimBatch",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "depositor",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "onBehalfOf",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slashedAmount",
"type": "uint256"
}
],
"name": "OnSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "delegator",
"type": "address"
}
],
"name": "SetDelegator",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "limit",
"type": "uint256"
}
],
"name": "SetDepositLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetDepositWhitelist",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetDepositorWhitelistStatus",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "SetIsDepositLimit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "slasher",
"type": "address"
}
],
"name": "SetSlasher",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "claimer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "burnedShares",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "mintedShares",
"type": "uint256"
}
],
"name": "Withdraw",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DELEGATOR_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSITOR_WHITELIST_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSIT_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPOSIT_WHITELIST_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "IS_DEPOSIT_LIMIT_SET_ROLE",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SLASHER_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "activeBalanceOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "activeBalanceOfAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "activeShares",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeSharesAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "activeSharesOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeSharesOfAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "activeStake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "activeStakeAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "address", "name": "spender", "type": "address" }
],
"name": "allowance",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "spender", "type": "address" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "approve",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "balanceOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "burner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "claim",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "recipient", "type": "address" },
{ "internalType": "uint256[]", "name": "epochs", "type": "uint256[]" }
],
"name": "claimBatch",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "collateral",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentEpoch",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delegator",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "onBehalfOf", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "deposit",
"outputs": [
{
"internalType": "uint256",
"name": "depositedAmount",
"type": "uint256"
},
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "depositLimit",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "depositWhitelist",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" }
],
"name": "epochAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "epochDuration",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "epochDurationInit",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" }
],
"name": "getRoleAdmin",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "hasRole",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "initialVersion", "type": "uint64" },
{ "internalType": "address", "name": "owner_", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "isDelegatorInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isDepositLimit",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "isDepositorWhitelisted",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isSlasherInitialized",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "isWithdrawalsClaimed",
"outputs": [{ "internalType": "bool", "name": "value", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint64", "name": "newVersion", "type": "uint64" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "migrate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "nextEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{ "internalType": "uint48", "name": "captureTimestamp", "type": "uint48" }
],
"name": "onSlash",
"outputs": [
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "previousEpochStart",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "claimer", "type": "address" },
{ "internalType": "uint256", "name": "shares", "type": "uint256" }
],
"name": "redeem",
"outputs": [
{
"internalType": "uint256",
"name": "withdrawnAssets",
"type": "uint256"
},
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "role", "type": "bytes32" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "delegator_", "type": "address" }
],
"name": "setDelegator",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "limit", "type": "uint256" }
],
"name": "setDepositLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "bool", "name": "status", "type": "bool" }],
"name": "setDepositWhitelist",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "bool", "name": "status", "type": "bool" }
],
"name": "setDepositorWhitelistStatus",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "bool", "name": "status", "type": "bool" }],
"name": "setIsDepositLimit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "slasher_", "type": "address" }
],
"name": "setSlasher",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "slashableBalanceOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "slasher",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" }
],
"name": "supportsInterface",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalStake",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "transfer",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "from", "type": "address" },
{ "internalType": "address", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "transferFrom",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "newOwner", "type": "address" }
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "claimer", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "withdraw",
"outputs": [
{ "internalType": "uint256", "name": "burnedShares", "type": "uint256" },
{ "internalType": "uint256", "name": "mintedShares", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "withdrawalShares",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "withdrawalSharesOf",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" }
],
"name": "withdrawals",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "epoch", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "withdrawalsOf",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
````
## File: abi/VetoSlasherABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "vaultFactory", "type": "address" },
{
"internalType": "address",
"name": "networkMiddlewareService",
"type": "address"
},
{
"internalType": "address",
"name": "networkRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "slasherFactory",
"type": "address"
},
{ "internalType": "uint64", "name": "entityType", "type": "uint64" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "AlreadySet", "type": "error" },
{ "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" },
{ "inputs": [], "name": "InsufficientBurnerGas", "type": "error" },
{ "inputs": [], "name": "InsufficientSlash", "type": "error" },
{ "inputs": [], "name": "InvalidCaptureTimestamp", "type": "error" },
{ "inputs": [], "name": "InvalidInitialization", "type": "error" },
{ "inputs": [], "name": "InvalidResolverSetEpochsDelay", "type": "error" },
{ "inputs": [], "name": "InvalidVetoDuration", "type": "error" },
{ "inputs": [], "name": "NoBurner", "type": "error" },
{ "inputs": [], "name": "NoResolver", "type": "error" },
{ "inputs": [], "name": "NotInitialized", "type": "error" },
{ "inputs": [], "name": "NotInitializing", "type": "error" },
{ "inputs": [], "name": "NotNetwork", "type": "error" },
{ "inputs": [], "name": "NotNetworkMiddleware", "type": "error" },
{ "inputs": [], "name": "NotResolver", "type": "error" },
{ "inputs": [], "name": "NotVault", "type": "error" },
{ "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" },
{
"inputs": [
{ "internalType": "uint8", "name": "bits", "type": "uint8" },
{ "internalType": "uint256", "name": "value", "type": "uint256" }
],
"name": "SafeCastOverflowedUintDowncast",
"type": "error"
},
{ "inputs": [], "name": "SlashPeriodEnded", "type": "error" },
{ "inputs": [], "name": "SlashRequestCompleted", "type": "error" },
{ "inputs": [], "name": "SlashRequestNotExist", "type": "error" },
{ "inputs": [], "name": "VetoPeriodEnded", "type": "error" },
{ "inputs": [], "name": "VetoPeriodNotEnded", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "slashIndex",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slashedAmount",
"type": "uint256"
}
],
"name": "ExecuteSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "slashIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slashAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{
"indexed": false,
"internalType": "uint48",
"name": "vetoDeadline",
"type": "uint48"
}
],
"name": "RequestSlash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "subnetwork",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "resolver",
"type": "address"
}
],
"name": "SetResolver",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "slashIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "resolver",
"type": "address"
}
],
"name": "VetoSlash",
"type": "event"
},
{
"inputs": [],
"name": "BURNER_GAS_LIMIT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "BURNER_RESERVE",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_MIDDLEWARE_SERVICE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "NETWORK_REGISTRY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TYPE",
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_FACTORY",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "cumulativeSlash",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "cumulativeSlashAt",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "slashIndex", "type": "uint256" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "executeSlash",
"outputs": [
{ "internalType": "uint256", "name": "slashedAmount", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "data", "type": "bytes" }],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "isBurnerHook",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" }
],
"name": "latestSlashedCaptureTimestamp",
"outputs": [
{ "internalType": "uint48", "name": "value", "type": "uint48" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "requestSlash",
"outputs": [
{ "internalType": "uint256", "name": "slashIndex", "type": "uint256" }
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "resolver",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "uint48", "name": "timestamp", "type": "uint48" },
{ "internalType": "bytes", "name": "hint", "type": "bytes" }
],
"name": "resolverAt",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "resolverSetEpochsDelay",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint96", "name": "identifier", "type": "uint96" },
{ "internalType": "address", "name": "resolver_", "type": "address" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "setResolver",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "slashRequests",
"outputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "uint48", "name": "vetoDeadline", "type": "uint48" },
{ "internalType": "bool", "name": "completed", "type": "bool" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "slashRequestsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes32", "name": "subnetwork", "type": "bytes32" },
{ "internalType": "address", "name": "operator", "type": "address" },
{
"internalType": "uint48",
"name": "captureTimestamp",
"type": "uint48"
},
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "slashableStake",
"outputs": [
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "target", "type": "address" },
{ "internalType": "bytes", "name": "data", "type": "bytes" }
],
"name": "staticDelegateCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vetoDuration",
"outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "slashIndex", "type": "uint256" },
{ "internalType": "bytes", "name": "hints", "type": "bytes" }
],
"name": "vetoSlash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
````
## File: abi/wstETH_BurnerABI.json
````json
[
{
"inputs": [
{ "internalType": "address", "name": "collateral", "type": "address" },
{
"internalType": "address",
"name": "lidoWithdrawalQueue",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ "inputs": [], "name": "InsufficientWithdrawal", "type": "error" },
{ "inputs": [], "name": "InvalidRequestId", "type": "error" },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "TriggerBurn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "requestIds",
"type": "uint256[]"
}
],
"name": "TriggerBurnBatch",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "caller",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "requestIds",
"type": "uint256[]"
}
],
"name": "TriggerWithdrawal",
"type": "event"
},
{
"inputs": [],
"name": "COLLATERAL",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIDO_WITHDRAWAL_QUEUE",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_STETH_WITHDRAWAL_AMOUNT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MIN_STETH_WITHDRAWAL_AMOUNT",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "STETH",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "index", "type": "uint256" },
{ "internalType": "uint256", "name": "maxRequestIds", "type": "uint256" }
],
"name": "requestIds",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "requestIdsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "requestId", "type": "uint256" }
],
"name": "triggerBurn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
},
{ "internalType": "uint256[]", "name": "hints", "type": "uint256[]" }
],
"name": "triggerBurnBatch",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "maxRequests", "type": "uint256" }
],
"name": "triggerWithdrawal",
"outputs": [
{
"internalType": "uint256[]",
"name": "requestIds_",
"type": "uint256[]"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{ "stateMutability": "payable", "type": "receive" }
]
````
## File: LICENSE
````
MIT License
Copyright (c) 2024 Symbiotic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
````
## File: README.md
````markdown
# Symbiotic CLI (symb)
Simple CLI tool for fetching data and interacting with Symbiotic core smart contracts.
[](https://deepwiki.com/symbioticfi/cli)
## Documentation
Can be found [here](https://docs.symbiotic.fi/guides/cli).
## Prerequisites
- Python >=3.8
## Install
```bash
pip3 install -r requirements.txt
```
## Usage
```
$ python3 symb.py
Usage: symb.py [GENERAL_OPTIONS] COMMAND [ARGS] [OPTIONS]
General options:
--help Show all the possible commands and exit.
--chain TEXT Chain ID to use.
--provider TEXT Ethereum provider URL [http(s)].
Commands:
--- for general use (related to Networks) ---
isnet Check if address is network.
middleware Get network middleware address.
nets List all networks.
netops List all operators opted in network.
netstakes Show stakes of all operators in network.
max-network-limit Get a maximum network limit at the vault's delegator.
network-limit Get a network limit at the vault's delegator.
pending-resolver Get a current resolver for a subnetwork in a vault.
resolver Get a pending resolver for a subnetwork in a vault.
--- for general use (related to Operators) ---
isop Check if address is operator.
ops List all operators.
opnets List all networks where operator is opted in.
op-vault-net-stake Get operator stake in vault for network (includes data about the operator's shares if NetworkRestakeDelegator).
opstakes Show operator stakes in all networks.
check-opt-in-network Check if operator is opted in to a network.
check-opt-in-vault Check if is opted in to a vault.
operator-network-limit Get an operator-network limit at the vault's delegator.
operator-network-shares Get operator-network shares at the vault's delegator.
total-operator-network-shares Get total operator-network shares at the vault's delegator.
--- for general use (related to Vaults) ---
isvault Check if address is vault.
vaults List all vaults.
vaultnets List all networks associated with the given vault.
vaultops List all operators opted into the given vault.
vaultnetsops List all operators and their associated networks for the given vault.
--- for general use (related to Stakers) ---
active-balance-of Get an active balance of a given account at a particular vault.
withdrawals-of Get some epoch's withdrawals of a given account at a particular vault.
withdrawals-claimed Check if some epoch's withdrawals of a given account at a particular vault are claimed.
--- for Networks ---
register-network Register the signer as a network.
set-max-network-limit Set a maximum network limit at the vault's delegator.
set-resolver Set a resolver for a subnetwork at VetoSlasher.
--- for Operators ---
register-operator Register the signer as an operator.
opt-in-network Opt-in to a network.
opt-in-network-signature Get a signature for opt-in to a network.
opt-in-vault Opt-in to a vault.
opt-in-vault-signature Get a signature for opt-in to a vault.
opt-out-network Opt-out from a network.
opt-out-network-signature Get a signature for opt-out from a network.
opt-out-vault Opt-out from a vault.
opt-out-vault-signature Get a signature for opt-out from a vault.
--- for Vault Curators ---
set-network-limit Set a network limit at the vault's delegator.
set-operator-network-limit Set an operator-network limit at the vault's delegator.
set-operator-network-shares Set an operator-network shares at the vault's delegator.
--- for Stakers ---
deposit Deposit to the vault.
withdraw Withdraw from the vault.
claim Claim a withdrawal for some epoch at the vault.
Options:
--help Show the command's description and exit.
--private-key TEXT Private key to sign transactions with (only for write functionality).
--ledger Flag if to use a ledger to sign transactions (only for write functionality).
--ledger-address TEXT Address of the ledger's account to use to sign transactions (only for write functionality).
```
````
## File: requirements.txt
````
click==8.1.3
web3==6.11.1
w3multicall==0.3.1
ledgereth==0.9.1
````
## File: symb.py
````python
class AddressType(click.ParamType)
⋮----
name = "ethereum_address"
pattern = re.compile(r"^0x[0-9a-fA-F]{40}$")
⋮----
def convert(self, value, param, ctx)
⋮----
class Bytes32Type(click.ParamType)
⋮----
name = "bytes32"
⋮----
value = value[2:]
⋮----
class Uint256Type(click.ParamType)
⋮----
name = "uint256"
⋮----
ivalue = int(value)
⋮----
class Uint96Type(click.ParamType)
⋮----
name = "uint96"
⋮----
class Uint48Type(click.ParamType)
⋮----
name = "uint48"
⋮----
class TokenAmountType(click.ParamType)
⋮----
name = "token_amount"
⋮----
def __init__(self, decimals=18)
⋮----
# Convert the string input to a Decimal
amount = Decimal(value)
⋮----
# Check for negative amounts
⋮----
class ChainType(click.ParamType)
⋮----
name = "chain"
⋮----
CHAIN_IDS = {
⋮----
value_str = str(value).lower()
⋮----
address_type = AddressType()
bytes32_type = Bytes32Type()
uint256_type = Uint256Type()
uint96_type = Uint96Type()
uint48_type = Uint48Type()
token_amount_type = TokenAmountType()
chain_type = ChainType()
⋮----
def load_abi(abis_path, name)
⋮----
class SymbioticCLI
⋮----
PROVIDERS = {
⋮----
ABIS_PATH = "./abi"
⋮----
ABIS = {
⋮----
ADDRESSES = {
⋮----
DELEGATOR_TYPES_ENTITIES = {
⋮----
DELEGATOR_TYPES_NAMES = {
⋮----
SLASHER_TYPES_NAMES = {
⋮----
SUBNETWORKS = [0, 1] # TODO: Generalize subnetworks
⋮----
def __init__(self, chain, provider)
⋮----
def init_contracts(self)
⋮----
def build_error_selector_map(self)
⋮----
parsed_abi = json.loads(open(f"{self.ABIS_PATH}/{abi_name}", "r").read())
⋮----
error_name = item["name"]
⋮----
input_types = []
type_sig = f"{error_name}()"
⋮----
input_types = [inp["type"] for inp in item["inputs"]]
type_sig = f"{error_name}({','.join(input_types)})"
⋮----
selector = Web3.keccak(text=type_sig)[:4].hex()
⋮----
def normalize_address(self, address)
⋮----
def get_subnetwork(self, net, subnet_id=0)
⋮----
net = self.normalize_address(net)
⋮----
def get_token_meta(self, token)
⋮----
token = self.normalize_address(token)
⋮----
w3_multicall = W3Multicall(self.w3)
⋮----
res = w3_multicall.call()
⋮----
res = [None, None]
⋮----
meta = {"symbol": "Unknown", "decimals": 0}
⋮----
meta = {"symbol": res[0], "decimals": int(res[1])}
⋮----
def get_middleware(self, net)
⋮----
def get_collateral(self, vault_address)
⋮----
vault_address = self.normalize_address(vault_address)
⋮----
def get_delegator(self, vault_address)
⋮----
def get_slasher(self, vault_address)
⋮----
def get_nets(self)
⋮----
total_entities = self.contracts["net_registry"].functions.totalEntities().call()
⋮----
nets = w3_multicall.call()
nets = [self.normalize_address(net) for net in nets]
⋮----
middlewares = w3_multicall.call()
middlewares = [self.normalize_address(middleware) for middleware in middlewares]
⋮----
def get_ops(self)
⋮----
total_entities = self.contracts["op_registry"].functions.totalEntities().call()
⋮----
ops = w3_multicall.call()
⋮----
def get_op_nets(self, operator)
⋮----
operator = self.normalize_address(operator)
nets = self.get_nets()
⋮----
optins = w3_multicall.call()
⋮----
def get_net_ops(self, net)
⋮----
ops = self.get_ops()
⋮----
def get_vaults(self)
⋮----
total_entities = (
⋮----
vaults = w3_multicall.call()
vaults = [self.normalize_address(vault) for vault in vaults]
⋮----
data = w3_multicall.call()
results = []
n = 4
⋮----
rev_result_idxs = []
⋮----
response = w3_multicall.call()
⋮----
def get_net_vaults(self, net)
⋮----
"""Fetch all vaults in a given network."""
⋮----
vaults = self.get_vaults()
vaults = [
⋮----
limits = w3_multicall.call()
⋮----
i = 0
⋮----
vault_limit = {}
⋮----
limit = limits[i]
⋮----
def get_net_ops_vaults(self, net)
⋮----
"""Fetch the stakes of all operators in a given network."""
⋮----
vaults = self.get_net_vaults(net)
ops = self.get_net_ops(net)
⋮----
stakes = w3_multicall.call()
results = [{"op": op, "vaults": []} for op in ops]
⋮----
vault_stake = {}
⋮----
stake = stakes[i]
⋮----
def get_vault_nets_ops_full(self, data)
⋮----
nets = self.get_vault_nets(data["vault"])
ops = self.get_vault_ops(data["vault"])
⋮----
results = [{"net": net["net"], "ops": []} for net in nets]
⋮----
op_stakes = {}
⋮----
def get_op_nets_vaults(self, op)
⋮----
"""Fetch stakes of an operator in all networks."""
op = self.normalize_address(op)
nets = self.get_op_nets(op)
⋮----
net_vaults = {}
⋮----
results = [{"net": net["net"], "vaults": []} for net in nets]
⋮----
def get_vault_ops(self, vault)
⋮----
"""Get all operators that are opted into a given vault."""
vault = self.normalize_address(vault)
⋮----
def get_vault_nets(self, vault)
⋮----
"""Get all networks associated with a given vault."""
⋮----
delegator = self.get_delegator(vault)
⋮----
net_associations = w3_multicall.call()
⋮----
network_limit = {}
⋮----
associated = net_associations[i]
⋮----
def get_vault_nets_ops(self, vault)
⋮----
"""Get all operators opted into the vault and their associated networks."""
⋮----
vault_ops = self.get_vault_ops(vault)
vault_nets = self.get_vault_nets(vault)
⋮----
results = {}
⋮----
def get_op_opted_in_vault(self, operator, vault)
⋮----
"""Check if an operator is opted into a vault."""
⋮----
def get_op_opted_in_net(self, operator, net)
⋮----
"""Check if an operator is opted into a network."""
⋮----
def get_resolver_set_epoch_delay(self, slasher_address)
⋮----
slasher_address = self.normalize_address(slasher_address)
⋮----
def get_resolver(self, slasher_address, subnetwork)
⋮----
def get_pending_resolver(self, slasher_address, subnetwork)
⋮----
timestamp = 2**48 - 1
⋮----
def get_entity_type(self, entity_address)
⋮----
entity_address = self.normalize_address(entity_address)
⋮----
def get_vault_epoch_duration(self, vault_address)
⋮----
def get_vault_current_epoch(self, vault_address)
⋮----
def get_vault_current_epoch_start(self, vault_address)
⋮----
def get_max_network_limit(self, delegator_address, subnetwork)
⋮----
delegator_address = self.normalize_address(delegator_address)
⋮----
def get_network_limit(self, delegator_address, subnetwork)
⋮----
operator_address = self.normalize_address(operator_address)
⋮----
def get_total_operator_network_shares(self, delegator_address, subnetwork)
⋮----
def get_stake(self, vault_address, subnetwork, operator_address)
⋮----
delegator_address = self.get_delegator(vault_address)
⋮----
def get_wei_amount(self, token, amount)
⋮----
meta = self.get_token_meta(token)
wei_amount = int(amount * 10 ** meta["decimals"])
⋮----
def get_token_amount(self, token, wei_amount)
⋮----
def get_allowance(self, token, owner, spender)
⋮----
owner = self.normalize_address(owner)
spender = self.normalize_address(spender)
⋮----
def get_active_balance(self, vault_address, account)
⋮----
account = self.normalize_address(account)
⋮----
def get_withdrawals(self, vault_address, epoch, account)
⋮----
def get_withdrawals_claimed(self, vault_address, epoch, account)
⋮----
def timestamp_to_datetime(self, timestamp)
⋮----
where = self.normalize_address(where)
who = self.get_address(private_key, ledger, ledger_address)
entity = "op_net_opt_in"
nonce = self.get_data(entity, self.addresses[entity], "nonces", who, where)
deadline = int(time()) + duration
⋮----
entity = "op_vault_opt_in"
⋮----
def decode_error_data(self, error_data: str)
⋮----
error_data = "0x" + error_data
⋮----
selector = error_data[:10]
encoded_args = error_data[10:]
⋮----
encoded_bytes = bytes.fromhex(encoded_args)
decoded = abi.decode(input_types, encoded_bytes)
⋮----
# "Error(string)"
⋮----
reason_str = abi.decode(["string"], encoded_bytes)[0]
⋮----
# "Panic(uint256)"
⋮----
panic_code = abi.decode(["uint256"], encoded_bytes)[0]
⋮----
def process_error(self, e)
⋮----
raw_msg = str(e.args[0])
m = re.search(r"(0x[0-9a-fA-F]+)", raw_msg)
⋮----
revert_hex = m.group(1)
decoded = self.decode_error_data(revert_hex)
⋮----
def print_indented(self, *args, indent=2)
⋮----
def get_data(self, entity, address, function_name, *args, **kwargs)
⋮----
address = self.normalize_address(address)
contract = self.w3.eth.contract(address=address, abi=self.ABIS[entity])
⋮----
def get_address(self, private_key, ledger, ledger_address)
⋮----
ledger_address = self.normalize_address(ledger_address)
⋮----
address = ledger_address
⋮----
address = ledgereth.accounts.get_accounts()[0].address
⋮----
address = Account.from_key(private_key).address
⋮----
def get_transaction(self, who, entity, address, function_name, *args, **kwargs)
⋮----
who = self.normalize_address(who)
⋮----
tx = self.get_transaction(
⋮----
def send_raw_transaction_and_wait(self, rawTransaction)
⋮----
tx_hash = self.w3.eth.send_raw_transaction(rawTransaction)
⋮----
def send_transaction(self, tx, private_key)
⋮----
signed_tx = self.w3.eth.account.sign_transaction(tx, private_key)
⋮----
def send_transaction_ledger(self, tx)
⋮----
to = self.normalize_address(to)
⋮----
account = ledgereth.accounts.find_account(ledger_address)
⋮----
account = ledgereth.accounts.get_accounts()[0]
⋮----
tx = self.get_transaction_ledger(
⋮----
tx_receipt = self.send_transaction_ledger(tx)
⋮----
who = Account.from_key(private_key).address
⋮----
tx = self.get_transaction(who, entity, to, function_name, *args)
⋮----
tx_receipt = self.send_transaction(tx, private_key)
⋮----
def get_domain_data(self, name, version, verifyingContract)
⋮----
verifyingContract = self.normalize_address(verifyingContract)
⋮----
def sign_typed_data_ledger(self, account, signable_message)
⋮----
domain_hash = signable_message.header
message_hash = signable_message.body
⋮----
signable_message = self.get_signable_message_from_typed_data(
⋮----
signed_message = self.sign_typed_data_ledger(account, signable_message)
signature = signed_message.signature
⋮----
signed_message = self.sign_typed_data(
signature = signed_message.signature.hex()
⋮----
def process_request(self, request_text)
⋮----
response = input(f"{request_text}")
⋮----
### GENERAL CLI COMMANDS ###
⋮----
@click.pass_context
def cli(ctx, chain, provider)
⋮----
## GENERAL NETWORK RELATED CLI COMMANDS ##
⋮----
@cli.command()
@click.argument("address", type=address_type)
@click.pass_context
def isnet(ctx, address)
⋮----
"""Check if address is network.
\b
ADDRESS - an address to check
"""
address = ctx.obj.normalize_address(address)
is_net = ctx.obj.contracts["net_registry"].functions.isEntity(address).call()
⋮----
@cli.command()
@click.argument("network_address", type=address_type)
@click.pass_context
def middleware(ctx, network_address)
⋮----
"""Get network middleware address.
\b
NETWORK_ADDRESS - an address of the network to get a middleware for
"""
network_address = ctx.obj.normalize_address(network_address)
middleware_address = ctx.obj.get_middleware(network_address)
⋮----
@click.pass_context
def nets(ctx, full)
⋮----
"""List all networks."""
nets = ctx.obj.get_nets()
⋮----
op_vaults = ctx.obj.get_net_ops_vaults(net["net"])
⋮----
vaults = {vault["vault"] for op in op_vaults for vault in op["vaults"]}
⋮----
@cli.command()
@click.argument("network_address", type=address_type)
@click.pass_context
def netops(ctx, network_address)
⋮----
"""List all operators opted in network.
\b
NETWORK_ADDRESS - an address of the network to get operators for
"""
⋮----
ops = ctx.obj.get_net_ops(network_address)
⋮----
@cli.command()
@click.argument("network_address", type=address_type)
@click.pass_context
def netstakes(ctx, network_address)
⋮----
"""Show stakes of all operators in network.
\b
NETWORK_ADDRESS - an address of the network to get a whole stake data for
"""
⋮----
opsvaults = ctx.obj.get_net_ops_vaults(network_address)
⋮----
total_stakes = {}
⋮----
collaterals = {}
⋮----
total_op_stake = ""
⋮----
stakes_sum = 0
token_meta = ctx.obj.get_token_meta(collateral)
⋮----
stake = sum(vault["stake"].values())
⋮----
## GENERAL OPERATOR RELATED CLI COMMANDS ##
⋮----
@cli.command()
@click.argument("address", type=address_type)
@click.pass_context
def isop(ctx, address)
⋮----
"""Check if address is operator.
\b
ADDRESS - an address to check
"""
⋮----
is_op = ctx.obj.contracts["op_registry"].functions.isEntity(address).call()
⋮----
@cli.command()
@click.pass_context
def ops(ctx)
⋮----
"""List all operators."""
ops = ctx.obj.get_ops()
⋮----
@cli.command()
@click.argument("operator_address", type=address_type)
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def op_vault_net_stake(ctx, operator_address, vault_address, network_address)
⋮----
"""Get operator stake in vault for network.
\b
OPERATOR_ADDRESS - an address of the operator to get a stake of
VAULT_ADDRESS - an address of the vault to get a stake at
NETWORK_ADDRESS - an address of the network to get a stake for
"""
operator_address = ctx.obj.normalize_address(operator_address)
vault_address = ctx.obj.normalize_address(vault_address)
⋮----
delegator = ctx.obj.get_delegator(vault_address)
delegator_type = ctx.obj.get_entity_type(delegator)
⋮----
subnetwork = ctx.obj.get_subnetwork(network_address, subnetwork_id)
⋮----
stake = ctx.obj.get_stake(vault_address, subnetwork, operator_address)
collateral = ctx.obj.get_collateral(vault_address)
⋮----
stake_normalized = stake / 10 ** token_meta["decimals"]
collateral_symbol = token_meta["symbol"]
⋮----
operator_network_shares = ctx.obj.get_operator_network_shares(
total_operator_network_shares = ctx.obj.get_total_operator_network_shares(
⋮----
percent = (
⋮----
@cli.command()
@click.argument("operator_address", type=address_type)
@click.pass_context
def opnets(ctx, operator_address)
⋮----
"""List all networks where operator is opted in.
\b
OPERATOR_ADDRESS - an address of the operator to get networks for
"""
⋮----
nets = ctx.obj.get_op_nets(operator_address)
⋮----
@cli.command()
@click.argument("operator_address", type=address_type)
@click.pass_context
def opstakes(ctx, operator_address)
⋮----
"""Show operator stakes in all networks.
\b
OPERATOR_ADDRESS - an address of the operator to get a whole stake data for
"""
⋮----
netsvaults = ctx.obj.get_op_nets_vaults(operator_address)
⋮----
total_net_stake = ""
⋮----
@cli.command()
@click.argument("operator_address", type=address_type)
@click.argument("vault_address", type=address_type)
@click.pass_context
def check_opt_in_vault(ctx, operator_address, vault_address)
⋮----
"""Check if operator is opted in to a vault.
\b
OPERATOR_ADDRESS - an address of the operator to check an opt-in status of
VAULT_ADDRESS - an address of the vault to check an opt-in status for
"""
⋮----
@cli.command()
@click.argument("operator_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def check_opt_in_network(ctx, operator_address, network_address)
⋮----
"""Check if operator is opted in to a network.
\b
OPERATOR_ADDRESS - an address of the operator to check an opt-in status of
NETWORK_ADDRESS - an address of the network to check an opt-in status for
"""
⋮----
## GENERAL VAULT RELATED CLI COMMANDS ##
⋮----
@cli.command()
@click.argument("address", type=address_type)
@click.pass_context
def isvault(ctx, address)
⋮----
"""Check if address is vault.
\b
ADDRESS - an address to check
"""
⋮----
is_vault = ctx.obj.contracts["vault_factory"].functions.isEntity(address).call()
⋮----
@click.pass_context
def vaults(ctx, full)
⋮----
"""List all vaults."""
vaults = ctx.obj.get_vaults()
⋮----
collateral_meta = ctx.obj.get_token_meta(vault["collateral"])
⋮----
slasher_type = ctx.obj.SLASHER_TYPES_NAMES.get(vault["slasher_type"], "Unknown")
⋮----
vault_data = ctx.obj.get_vault_nets_ops_full(vault)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.pass_context
def vaultops(ctx, vault_address)
⋮----
"""List all operators opted into the given vault.
\b
VAULT_ADDRESS - an address of the vault to get all operators for
"""
⋮----
ops = ctx.obj.get_vault_ops(vault_address)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.pass_context
def vaultnets(ctx, vault_address)
⋮----
"""List all networks associated with the given vault.
\b
VAULT_ADDRESS - an address of the vault to get all networks for
"""
⋮----
nets = ctx.obj.get_vault_nets(vault_address)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.pass_context
def vaultnetsops(ctx, vault_address)
⋮----
"""List all operators and their associated networks for the given vault.
\b
VAULT_ADDRESS - an address of the vault to adjust the delegations for
"""
⋮----
nets_ops = ctx.obj.get_vault_nets_ops(vault_address)
⋮----
## GENERAL STAKER RELATED CLI COMMANDS ##
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("address", type=address_type)
@click.pass_context
def active_balance_of(ctx, vault_address, address)
⋮----
"""Get an active balance of a given account at a particular vault.
\b
VAULT_ADDRESS - an address of the vault
ADDRESS - an address to get an active balance for
"""
⋮----
token_address = ctx.obj.get_collateral(vault_address)
symbol = ctx.obj.get_token_meta(token_address)["symbol"]
active_balance_wei = ctx.obj.get_active_balance(vault_address, address)
active_balance = ctx.obj.get_token_amount(token_address, active_balance_wei)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("epoch", type=uint256_type)
@click.argument("address", type=address_type)
@click.pass_context
def withdrawals_of(ctx, vault_address, epoch, address)
⋮----
"""Get some epoch's withdrawals of a given account at a particular vault.
\b
VAULT_ADDRESS - an address of the vault
EPOCH - an epoch to get withdrawals for
ADDRESS - an address to get withdrawals for
"""
⋮----
withdrawals_wei = ctx.obj.get_withdrawals(vault_address, epoch, address)
withdrawals = ctx.obj.get_token_amount(token_address, withdrawals_wei)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("epoch", type=uint256_type)
@click.argument("address", type=address_type)
@click.pass_context
def withdrawals_claimed(ctx, vault_address, epoch, address)
⋮----
"""Check if some epoch's withdrawals of a given account at a particular vault are claimed.
\b
VAULT_ADDRESS - an address of the vault
EPOCH - an epoch to check for
ADDRESS - an address to get if the withdrawals are claimed for
"""
⋮----
withdrawals_claimed = ctx.obj.get_withdrawals_claimed(vault_address, epoch, address)
⋮----
### NETWORK CLI COMMANDS ###
⋮----
@click.pass_context
def register_network(ctx, private_key, ledger, ledger_address)
⋮----
"""Register the signer as a network."""
⋮----
"""Set a maximum network limit at the vault's delegator.
\b
VAULT_ADDRESS - an address of the vault to set a maximum limit for
MAX_LIMIT - a maximum amount of stake a network is ready to get from the vault (in wei)
SUBNETWORK_ID - an identifier of the subnetwork to set a maximum limit for (default is 0)
"""
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def max_network_limit(ctx, vault_address, network_address)
⋮----
"""Get a current maximum network limit for a subnetwork in a vault.
\b
VAULT_ADDRESS - an address of the vault to get a maximum network limit for
NETWORK_ADDRESS - an address of the network to get a maximum network limit for
"""
⋮----
max_network_limit = ctx.obj.get_max_network_limit(delegator, subnetwork)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def resolver(ctx, vault_address, network_address)
⋮----
"""Get a current resolver for a subnetwork in a vault.
\b
VAULT_ADDRESS - an address of the vault to get a resolver for
NETWORK_ADDRESS - an address of the network to get a resolver for
"""
⋮----
slasher = ctx.obj.get_slasher(vault_address)
slasher_type = ctx.obj.get_entity_type(slasher)
⋮----
resolver = ctx.obj.get_resolver(slasher, subnetwork)
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def pending_resolver(ctx, vault_address, network_address)
⋮----
"""Get a pending resolver for a subnetwork in a vault.
\b
VAULT_ADDRESS - an address of the vault to get a pending resolver for
NETWORK_ADDRESS - an address of the network to get a pending resolver for
"""
⋮----
pending_resolver = ctx.obj.get_pending_resolver(slasher, subnetwork)
⋮----
"""Set a resolver for a subnetwork at VetoSlasher.
\b
VAULT_ADDRESS - an address of the vault to set a resolver for
RESOLVER - an address of the resolver to set
SUBNETWORK_ID - an identifier of the subnetwork to set a resolver for (default is 0)
"""
⋮----
resolver = ctx.obj.normalize_address(resolver)
⋮----
net = ctx.obj.get_address(private_key, ledger, ledger_address)
⋮----
subnetwork = ctx.obj.get_subnetwork(net, subnetwork_id)
⋮----
current_resolver = ctx.obj.get_resolver(slasher, subnetwork)
⋮----
new_timestamp = ctx.obj.get_vault_current_epoch_start(
new_datetime = ctx.obj.timestamp_to_datetime(new_timestamp)
⋮----
### OPERATOR CLI COMMANDS ###
⋮----
@click.pass_context
def register_operator(ctx, private_key, ledger, ledger_address)
⋮----
"""Register the signer as an operator."""
⋮----
@click.pass_context
def opt_in_vault(ctx, vault_address, private_key, ledger, ledger_address)
⋮----
"""Opt-in to a vault.
\b
VAULT_ADDRESS - an address of the vault to opt into
"""
⋮----
"""Get a signature for opt-in to a vault.
\b
VAULT_ADDRESS - an address of the vault to opt into
DURATION - a period of time (in seconds) after which the signature will expire (default is 7 days)
"""
⋮----
@click.pass_context
def opt_out_vault(ctx, vault_address, private_key, ledger, ledger_address)
⋮----
"""Opt-out from a vault.
\b
VAULT_ADDRESS - an address of the vault to opt out from
"""
⋮----
"""Get a signature for opt-out from a vault.
\b
VAULT_ADDRESS - an address of the vault to opt out from
DURATION - a period of time (in seconds) after which the signature will expire (default is 7 days)
"""
⋮----
@click.pass_context
def opt_in_network(ctx, network_address, private_key, ledger, ledger_address)
⋮----
"""Opt-in to a network.
\b
NETWORK_ADDRESS - an address of the network to opt into
"""
⋮----
"""Get a signature for opt-in to a network.
\b
NETWORK_ADDRESS - an address of the network to opt into
DURATION - a period of time (in seconds) after which the signature will expire (default is 7 days)
"""
⋮----
@click.pass_context
def opt_out_network(ctx, network_address, private_key, ledger, ledger_address)
⋮----
"""Opt-out from a network.
\b
NETWORK_ADDRESS - an address of the network to opt out from
"""
⋮----
"""Get a signature for opt-out from a network.
\b
NETWORK_ADDRESS - an address of the network to opt out from
DURATION - a period of time (in seconds) after which the signature will expire (default is 7 days)
"""
⋮----
### VAULT CURATOR CLI COMMANDS ###
⋮----
"""Set a network limit at the vault's delegator.
\b
VAULT_ADDRESS - an address of the vault to adjust the delegations for
NETWORK_ADDRESS - an address of the network to set a limit for
LIMIT - a maximum amount of stake the network can get (in wei)
SUBNETWORK_ID - an identifier of the subnetwork to adjust the delegations for (default is 0)
"""
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def network_limit(ctx, vault_address, network_address)
⋮----
"""Get a current network limit for a subnetwork in a vault.
\b
VAULT_ADDRESS - an address of the vault to get a network limit for
NETWORK_ADDRESS - an address of the network to get a network limit for
"""
⋮----
network_limit = ctx.obj.get_network_limit(delegator, subnetwork)
⋮----
"""Set an operator-network limit at the vault's delegator.
\b
VAULT_ADDRESS - an address of the vault to adjust the delegations for
NETWORK_ADDRESS - an address of the network
OPERATOR_ADDRESS - an address of the operator to set a limit in the network for
LIMIT - a maximum amount of stake the operator can get in the network (in wei)
SUBNETWORK_ID - an identifier of the subnetwork to adjust the delegations for (default is 0)
"""
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.argument("operator_address", type=address_type)
@click.pass_context
def operator_network_limit(ctx, vault_address, network_address, operator_address)
⋮----
"""Get a current operator-network limit for an operator in the subnetwork.
\b
VAULT_ADDRESS - an address of the vault to get a operator-network limit for
NETWORK_ADDRESS - an address of the network to get a operator-network limit for
OPERATOR_ADDRESS - an address of the operator to get a operator-network limit for
"""
⋮----
operator_network_limit = ctx.obj.get_operator_network_limit(
⋮----
"""Set an operator-network shares at the vault's delegator.
\b
VAULT_ADDRESS - an address of the vault to adjust the delegations for
NETWORK_ADDRESS - an address of the network
OPERATOR_ADDRESS - an address of the operator to set shares in the network for
SHARES - an amount of shares (determines a percent = operator shares / total shares of the network stake the operator can get) to set for the operator
SUBNETWORK_ID - an identifier of the subnetwork to adjust the delegations for (default is 0)
"""
⋮----
new_total_operator_network_shares = (
⋮----
percentage = (
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.argument("operator_address", type=address_type)
@click.pass_context
def operator_network_shares(ctx, vault_address, network_address, operator_address)
⋮----
"""Get current operator-network shares for an operator in the subnetwork.
\b
VAULT_ADDRESS - an address of the vault to get operator-network shares for
NETWORK_ADDRESS - an address of the network to get operator-network shares for
OPERATOR_ADDRESS - an address of the operator to get operator-network shares for
"""
⋮----
@cli.command()
@click.argument("vault_address", type=address_type)
@click.argument("network_address", type=address_type)
@click.pass_context
def total_operator_network_shares(ctx, vault_address, network_address)
⋮----
"""Get current total operator-network shares for a subnetwork in a vault.
\b
VAULT_ADDRESS - an address of the vault to get total operator-network shares for
NETWORK_ADDRESS - an address of the network to get total operator-network shares for
"""
⋮----
### STAKER CLI COMMANDS ###
⋮----
"""Deposit to the vault.
\b
VAULT_ADDRESS - an address of the vault to deposit to
AMOUNT - an amount of tokens to deposit (in the token value, e.g., 1000 for 1000 ETH)
ON_BEHALF_OF - an address to make a deposit on behalf of (default: address of the signer)
"""
⋮----
signer = ctx.obj.get_address(private_key, ledger, ledger_address)
on_behalf_of = ctx.obj.normalize_address(on_behalf_of)
⋮----
on_behalf_of = signer
⋮----
wei_amount = ctx.obj.get_wei_amount(token_address, amount)
⋮----
allowance = ctx.obj.get_allowance(token_address, signer, vault_address)
⋮----
"""Withdraw from the vault.
\b
VAULT_ADDRESS - an address of the vault to withdraw from
AMOUNT - an amount of tokens to withdraw (in the token value, e.g., 1000 for 1000 ETH)
CLAIMER - an address that needs to claim the withdrawal (default: address of the signer)
"""
⋮----
claimer = ctx.obj.normalize_address(claimer)
⋮----
claimer = signer
⋮----
epoch_duration = ctx.obj.get_vault_epoch_duration(vault_address)
current_epoch = ctx.obj.get_vault_current_epoch(vault_address)
current_epoch_start = ctx.obj.get_vault_current_epoch_start(vault_address)
⋮----
next_epoch = current_epoch + 1
next_epoch_end = current_epoch_start + 2 * epoch_duration
⋮----
"""Claim a withdrawal for some epoch at the vault.
\b
VAULT_ADDRESS - an address of the vault to claim from
EPOCH - an epoch number to claim a withdrawal for
RECIPIENT - an address that will receive the tokens (default: address of the signer)
"""
⋮----
recipient = ctx.obj.normalize_address(recipient)
⋮----
recipient = signer
⋮----
withdrawals_wei = ctx.obj.get_withdrawals(vault_address, epoch, signer)
⋮----
withdrawals_claimed = ctx.obj.get_withdrawals_claimed(vault_address, epoch, signer)
````