Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegators tests #7

Merged
merged 8 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions src/contracts/delegator/BaseDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,6 @@ contract BaseDelegator is Entity, AccessControlUpgradeable, IBaseDelegator {
*/
mapping(address network => uint256 value) public maxNetworkLimit;

modifier onlySlasher() {
if (IVault(vault).slasher() != msg.sender) {
revert NotSlasher();
}
_;
}

constructor(
address networkRegistry,
address vaultFactory,
Expand Down Expand Up @@ -119,11 +112,11 @@ contract BaseDelegator is Entity, AccessControlUpgradeable, IBaseDelegator {
uint48 delta = nextEpochStart - Time.timestamp();
if (Time.timestamp() + duration >= nextEpochStart) {
minOperatorNetworkStakeDuring_ =
Math.min(minOperatorNetworkStakeDuring_, operatorNetworkStakeIn(operator, network, delta));
Math.min(minOperatorNetworkStakeDuring_, operatorNetworkStakeIn(network, operator, delta));
}
if (Time.timestamp() + duration >= nextEpochStart + epochDuration) {
minOperatorNetworkStakeDuring_ = Math.min(
minOperatorNetworkStakeDuring_, operatorNetworkStakeIn(operator, network, delta + epochDuration)
minOperatorNetworkStakeDuring_, operatorNetworkStakeIn(network, operator, delta + epochDuration)
);
}
}
Expand All @@ -150,7 +143,11 @@ contract BaseDelegator is Entity, AccessControlUpgradeable, IBaseDelegator {
/**
* @inheritdoc IBaseDelegator
*/
function onSlash(address network, address operator, uint256 slashedAmount) external onlySlasher {
function onSlash(address network, address operator, uint256 slashedAmount) external {
if (IVault(vault).slasher() != msg.sender) {
revert NotSlasher();
}

_onSlash(network, operator, slashedAmount);

emit OnSlash(network, operator, slashedAmount);
Expand All @@ -160,6 +157,24 @@ contract BaseDelegator is Entity, AccessControlUpgradeable, IBaseDelegator {

function _onSlash(address network, address operator, uint256 slashedAmount) internal virtual {}

function _insertCheckpoint(Checkpoints.Trace256 storage checkpoints, uint48 key, uint256 value) internal {
(, uint48 latestTimestamp1, uint256 latestValue1) = checkpoints.latestCheckpoint();
if (key < latestTimestamp1) {
checkpoints.pop();
(, uint48 latestTimestamp2, uint256 latestValue2) = checkpoints.latestCheckpoint();
if (key < latestTimestamp2) {
checkpoints.pop();
checkpoints.push(key, value);
checkpoints.push(latestTimestamp2, latestValue2);
} else {
checkpoints.push(key, value);
}
checkpoints.push(latestTimestamp1, latestValue1);
} else {
checkpoints.push(key, value);
}
}

function _initializeInternal(
address vault_,
bytes memory data
Expand Down
21 changes: 13 additions & 8 deletions src/contracts/delegator/FullRestakeDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
address operator,
uint48 duration
) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
return Math.min(networkStakeIn(network, duration), operatorNetworkLimitIn(network, operator, duration));
return Math.min(
IVault(vault).totalSupplyIn(duration),
Math.min(networkLimitIn(network, duration), operatorNetworkLimitIn(network, operator, duration))
);
}

/**
Expand All @@ -129,7 +132,9 @@ contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
address network,
address operator
) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
return Math.min(networkStake(network), operatorNetworkLimit(network, operator));
return Math.min(
IVault(vault).totalSupply(), Math.min(networkLimit(network), operatorNetworkLimit(network, operator))
);
}

/**
Expand All @@ -144,7 +149,7 @@ contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
? Time.timestamp()
: IVault(vault).currentEpochStart() + 2 * IVault(vault).epochDuration();

_networkLimit[network].push(timestamp, amount);
_insertCheckpoint(_networkLimit[network], timestamp, amount);

emit SetNetworkLimit(network, amount);
}
Expand All @@ -162,16 +167,16 @@ contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
if (amount > operatorNetworkLimit(network, operator)) {
timestamp = Time.timestamp();
totalOperatorNetworkLimit_ =
totalOperatorNetworkLimit(network) + amount - operatorNetworkLimit(network, operator);
totalOperatorNetworkLimit(network) - operatorNetworkLimit(network, operator) + amount;
} else {
timestamp = IVault(vault).currentEpochStart() + 2 * IVault(vault).epochDuration();
totalOperatorNetworkLimit_ = _totalOperatorNetworkLimit[network].latest() + amount
- _operatorNetworkLimit[network][operator].latest();
totalOperatorNetworkLimit_ = _totalOperatorNetworkLimit[network].latest()
- _operatorNetworkLimit[network][operator].latest() + amount;
}

_totalOperatorNetworkLimit[network].push(timestamp, totalOperatorNetworkLimit_);
_insertCheckpoint(_totalOperatorNetworkLimit[network], timestamp, totalOperatorNetworkLimit_);

_operatorNetworkLimit[network][operator].push(timestamp, amount);
_insertCheckpoint(_operatorNetworkLimit[network][operator], timestamp, amount);

emit SetOperatorNetworkLimit(network, operator, amount);
}
Expand Down
23 changes: 18 additions & 5 deletions src/contracts/delegator/NetworkRestakeDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,19 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
address network,
uint48 duration
) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
if (totalOperatorNetworkSharesIn(network, duration) == 0) {
return 0;
}
return Math.min(IVault(vault).totalSupplyIn(duration), networkLimitIn(network, duration));
}

/**
* @inheritdoc IBaseDelegator
*/
function networkStake(address network) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
if (totalOperatorNetworkShares(network) == 0) {
return 0;
}
return Math.min(IVault(vault).totalSupply(), networkLimit(network));
}

Expand All @@ -119,8 +125,12 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
address operator,
uint48 duration
) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
uint256 totalOperatorNetworkSharesIn_ = totalOperatorNetworkSharesIn(network, duration);
if (totalOperatorNetworkSharesIn_ == 0) {
return 0;
}
return operatorNetworkSharesIn(network, operator, duration).mulDiv(
networkStakeIn(network, duration), totalOperatorNetworkSharesIn(network, duration)
networkStakeIn(network, duration), totalOperatorNetworkSharesIn_
);
}

Expand All @@ -131,8 +141,11 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
address network,
address operator
) public view override(IBaseDelegator, BaseDelegator) returns (uint256) {
return
operatorNetworkShares(network, operator).mulDiv(networkStake(network), totalOperatorNetworkShares(network));
uint256 totalOperatorNetworkShares_ = totalOperatorNetworkShares(network);
if (totalOperatorNetworkShares_ == 0) {
return 0;
}
return operatorNetworkShares(network, operator).mulDiv(networkStake(network), totalOperatorNetworkShares_);
}

/**
Expand All @@ -147,7 +160,7 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
? Time.timestamp()
: IVault(vault).currentEpochStart() + 2 * IVault(vault).epochDuration();

_networkLimit[network].push(timestamp, amount);
_insertCheckpoint(_networkLimit[network], timestamp, amount);

emit SetNetworkLimit(network, amount);
}
Expand All @@ -164,7 +177,7 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {

_totalOperatorNetworkShares[network].push(
timestamp,
_totalOperatorNetworkShares[network].latest() + shares - _operatorNetworkShares[network][operator].latest()
_totalOperatorNetworkShares[network].latest() - _operatorNetworkShares[network][operator].latest() + shares
);

_operatorNetworkShares[network][operator].push(timestamp, shares);
Expand Down
12 changes: 6 additions & 6 deletions src/contracts/libraries/Checkpoints.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ library Checkpoints {
function upperLookupRecentCheckpoint(
Trace208 storage self,
uint48 key
) internal view returns (bool, uint48, uint208) {
) internal view returns (bool, uint48, uint208, uint256) {
uint256 len = self._trace._checkpoints.length;

uint256 low = 0;
Expand All @@ -90,11 +90,11 @@ library Checkpoints {
uint256 pos = _upperBinaryLookup(self._trace._checkpoints, key, low, high);

if (pos == 0) {
return (false, 0, 0);
return (false, 0, 0, 0);
}

OZCheckpoints.Checkpoint208 memory checkpoint = _unsafeAccess(self._trace._checkpoints, pos - 1);
return (true, checkpoint._key, checkpoint._value);
return (true, checkpoint._key, checkpoint._value, pos - 1);
}

/**
Expand Down Expand Up @@ -177,7 +177,7 @@ library Checkpoints {
function upperLookupRecentCheckpoint(
Trace256 storage self,
uint48 key
) internal view returns (bool, uint48, uint256) {
) internal view returns (bool, uint48, uint256, uint256) {
uint256 len = self._trace._checkpoints.length;

uint256 low = 0;
Expand All @@ -195,11 +195,11 @@ library Checkpoints {
uint256 pos = _upperBinaryLookup(self._trace._checkpoints, key, low, high);

if (pos == 0) {
return (false, 0, 0);
return (false, 0, 0, 0);
}

OZCheckpoints.Checkpoint208 memory checkpoint = _unsafeAccess(self._trace._checkpoints, pos - 1);
return (true, checkpoint._key, self._values[checkpoint._value]);
return (true, checkpoint._key, self._values[checkpoint._value], pos - 1);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/libraries/ERC4626Math.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ library ERC4626Math {
}

function _decimalsOffset() private pure returns (uint8) {
return 3;
return 0;
}
}
7 changes: 1 addition & 6 deletions src/contracts/slasher/VetoSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@ contract VetoSlasher is BaseSlasher, AccessControlUpgradeable, IVetoSlasher {
/**
* @inheritdoc IVetoSlasher
*/
uint256 public SHARES_BASE = 10 ** 18;

/**
* @inheritdoc IVetoSlasher
*/
bytes32 public constant RESOLVER_SHARES_SET_ROLE = keccak256("RESOLVER_SHARES_SET_ROLE");
uint256 public constant SHARES_BASE = 10 ** 18;

/**
* @inheritdoc IVetoSlasher
Expand Down
18 changes: 5 additions & 13 deletions src/contracts/vault/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
using SafeCast for uint256;
using SafeERC20 for IERC20;

modifier onlySlasher() {
if (msg.sender != slasher()) {
revert NotSlasher();
}
_;
}

/**
* @inheritdoc IVault
*/
Expand Down Expand Up @@ -203,7 +196,11 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
/**
* @inheritdoc IVault
*/
function onSlash(uint256 slashedAmount) external onlySlasher {
function onSlash(uint256 slashedAmount) external {
if (msg.sender != slasher()) {
revert NotSlasher();
}

if (slashedAmount == 0) {
revert InsufficientSlash();
}
Expand All @@ -226,11 +223,6 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
if (activeSupply_ < activeSlashed) {
withdrawalsSlashed += activeSlashed - activeSupply_;
activeSlashed = activeSupply_;

if (withdrawals_ < withdrawalsSlashed) {
nextWithdrawalsSlashed += withdrawalsSlashed - withdrawals_;
withdrawalsSlashed = withdrawals_;
}
}

_activeSupplies.push(Time.timestamp(), activeSupply_ - activeSlashed);
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/vault/VaultStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ contract VaultStorage is IVaultStorage {
function activeSharesOfCheckpointAt(
address account,
uint48 timestamp
) external view returns (bool, uint48, uint256) {
) external view returns (bool, uint48, uint256, uint256) {
return _activeSharesOf[account].upperLookupRecentCheckpoint(timestamp);
}

Expand Down
2 changes: 0 additions & 2 deletions src/interfaces/IVaultConfigurator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ pragma solidity 0.8.25;
import {IVault} from "src/interfaces/vault/IVault.sol";

interface IVaultConfigurator {
error InvalidSlashDuration();

/**
* @notice Initial parameters needed for a vault with a delegator and a slashher deployment.
* @param version entity's version to use
Expand Down
6 changes: 0 additions & 6 deletions src/interfaces/slasher/IVetoSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ interface IVetoSlasher {
*/
function SHARES_BASE() external view returns (uint256);

/**
* @notice Get a resolver shares setter's role.
* @return identifier of the resolver shares setter role
*/
function RESOLVER_SHARES_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the network registry's address.
* @return address of the network registry
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/vault/IVaultStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,12 @@ interface IVaultStorage {
* @return if the checkpoint exists
* @return timestamp time point of the checkpoint
* @return amount of active shares at the checkpoint
* @return index of the checkpoint
*/
function activeSharesOfCheckpointAt(
address account,
uint48 timestamp
) external view returns (bool, uint48, uint256);
) external view returns (bool, uint48, uint256, uint256);

/**
* @notice Get an amount of active shares for a particular account.
Expand Down
5 changes: 3 additions & 2 deletions test/DelegatorFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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";

contract DelegatorFactoryTest is Test {
Expand Down Expand Up @@ -179,10 +180,10 @@ contract DelegatorFactoryTest is Test {
abi.encode(
vault_,
abi.encode(
INetworkRestakeDelegator.InitParams({
IFullRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({defaultAdminRoleHolder: bob}),
networkLimitSetRoleHolder: bob,
operatorNetworkSharesSetRoleHolder: bob
operatorNetworkLimitSetRoleHolder: bob
})
)
)
Expand Down
1 change: 1 addition & 0 deletions test/SlasherFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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";

Expand Down
1 change: 1 addition & 0 deletions test/VaultConfigurator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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";

contract VaultConfiguratorTest is Test {
Expand Down
1 change: 1 addition & 0 deletions test/VaultFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ 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";

contract VaultFactoryTest is Test {
Expand Down
Loading
Loading