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

Payments storage packing #942

Merged
merged 7 commits into from
Dec 12, 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
38 changes: 36 additions & 2 deletions contracts/script/EigenDADeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {IEigenDAThresholdRegistry} from "../src/interfaces/IEigenDAThresholdRegi
import {IEigenDABatchMetadataStorage} from "../src/interfaces/IEigenDABatchMetadataStorage.sol";
import {IEigenDASignatureVerifier} from "../src/interfaces/IEigenDASignatureVerifier.sol";
import {IEigenDARelayRegistry} from "../src/interfaces/IEigenDARelayRegistry.sol";
import {IPaymentVault} from "../src/interfaces/IPaymentVault.sol";
import {PaymentVault} from "../src/payments/PaymentVault.sol";
import {EigenDARelayRegistry} from "../src/core/EigenDARelayRegistry.sol";
import {ISocketRegistry, SocketRegistry} from "eigenlayer-middleware/SocketRegistry.sol";

import {DeployOpenEigenLayer, ProxyAdmin, ERC20PresetFixedSupply, TransparentUpgradeableProxy, IPauserRegistry} from "./DeployOpenEigenLayer.s.sol";
import "forge-std/Test.sol";
import "forge-std/Script.sol";
Expand All @@ -49,6 +50,7 @@ contract EigenDADeployer is DeployOpenEigenLayer {
IStakeRegistry public stakeRegistry;
ISocketRegistry public socketRegistry;
OperatorStateRetriever public operatorStateRetriever;
IPaymentVault public paymentVault;
EigenDARelayRegistry public eigenDARelayRegistry;

BLSApkRegistry public apkRegistryImplementation;
Expand All @@ -59,6 +61,14 @@ contract EigenDADeployer is DeployOpenEigenLayer {
EigenDAThresholdRegistry public eigenDAThresholdRegistryImplementation;
EigenDARelayRegistry public eigenDARelayRegistryImplementation;
ISocketRegistry public socketRegistryImplementation;
IPaymentVault public paymentVaultImplementation;

uint64 _minNumSymbols = 4096;
uint64 _pricePerSymbol = 0.4470 gwei;
uint64 _priceUpdateCooldown = 1;
uint64 _globalSymbolsPerPeriod = 131072;
uint64 _reservationPeriodInterval = 300;
uint64 _globalRatePeriodInterval = 30;

struct AddressConfig {
address eigenLayerCommunityMultisig;
Expand Down Expand Up @@ -135,6 +145,29 @@ contract EigenDADeployer is DeployOpenEigenLayer {
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);

{
paymentVault = IPaymentVault(
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);

paymentVaultImplementation = new PaymentVault();

eigenDAProxyAdmin.upgradeAndCall(
TransparentUpgradeableProxy(payable(address(paymentVault))),
address(paymentVaultImplementation),
abi.encodeWithSelector(
PaymentVault.initialize.selector,
addressConfig.eigenDACommunityMultisig,
_minNumSymbols,
_pricePerSymbol,
_priceUpdateCooldown,
_globalSymbolsPerPeriod,
_reservationPeriodInterval,
_globalRatePeriodInterval
)
);
}

indexRegistryImplementation = new IndexRegistry(
registryCoordinator
);
Expand Down Expand Up @@ -222,7 +255,8 @@ contract EigenDADeployer is DeployOpenEigenLayer {
registryCoordinator,
stakeRegistry,
eigenDAThresholdRegistry,
eigenDARelayRegistry
eigenDARelayRegistry,
paymentVault
);

address[] memory confirmers = new address[](1);
Expand Down
6 changes: 4 additions & 2 deletions contracts/src/core/EigenDAServiceManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {IRegistryCoordinator} from "eigenlayer-middleware/interfaces/IRegistryCo
import {IStakeRegistry} from "eigenlayer-middleware/interfaces/IStakeRegistry.sol";
import {IEigenDAThresholdRegistry} from "../interfaces/IEigenDAThresholdRegistry.sol";
import {IEigenDARelayRegistry} from "../interfaces/IEigenDARelayRegistry.sol";
import {IPaymentVault} from "../interfaces/IPaymentVault.sol";
import {EigenDAServiceManagerStorage} from "./EigenDAServiceManagerStorage.sol";
import {EigenDAHasher} from "../libraries/EigenDAHasher.sol";
import "../interfaces/IEigenDAStructs.sol";
Expand Down Expand Up @@ -40,11 +41,12 @@ contract EigenDAServiceManager is EigenDAServiceManagerStorage, ServiceManagerBa
IRegistryCoordinator __registryCoordinator,
IStakeRegistry __stakeRegistry,
IEigenDAThresholdRegistry __eigenDAThresholdRegistry,
IEigenDARelayRegistry __eigenDARelayRegistry
IEigenDARelayRegistry __eigenDARelayRegistry,
IPaymentVault __paymentVault
)
BLSSignatureChecker(__registryCoordinator)
ServiceManagerBase(__avsDirectory, __rewardsCoordinator, __registryCoordinator, __stakeRegistry)
EigenDAServiceManagerStorage(__eigenDAThresholdRegistry, __eigenDARelayRegistry)
EigenDAServiceManagerStorage(__eigenDAThresholdRegistry, __eigenDARelayRegistry, __paymentVault)
{
_disableInitializers();
}
Expand Down
8 changes: 6 additions & 2 deletions contracts/src/core/EigenDAServiceManagerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.9;
import {IEigenDAServiceManager} from "../interfaces/IEigenDAServiceManager.sol";
import {IEigenDAThresholdRegistry} from "../interfaces/IEigenDAThresholdRegistry.sol";
import {IEigenDARelayRegistry} from "../interfaces/IEigenDARelayRegistry.sol";
import {IPaymentVault} from "../interfaces/IPaymentVault.sol";

/**
* @title Storage variables for the `EigenDAServiceManager` contract.
Expand Down Expand Up @@ -39,13 +40,16 @@ abstract contract EigenDAServiceManagerStorage is IEigenDAServiceManager {

IEigenDAThresholdRegistry public immutable eigenDAThresholdRegistry;
IEigenDARelayRegistry public immutable eigenDARelayRegistry;

IPaymentVault public immutable paymentVault;

constructor(
IEigenDAThresholdRegistry _eigenDAThresholdRegistry,
IEigenDARelayRegistry _eigenDARelayRegistry
IEigenDARelayRegistry _eigenDARelayRegistry,
IPaymentVault _paymentVault
) {
eigenDAThresholdRegistry = _eigenDAThresholdRegistry;
eigenDARelayRegistry = _eigenDARelayRegistry;
paymentVault = _paymentVault;
}

/// @notice The current batchId
Expand Down
40 changes: 22 additions & 18 deletions contracts/src/interfaces/IPaymentVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,32 @@ interface IPaymentVault {
uint64 symbolsPerSecond; // Number of symbols reserved per second
uint64 startTimestamp; // timestamp of epoch where reservation begins
uint64 endTimestamp; // timestamp of epoch where reservation ends
bytes quorumNumbers; // quorum numbers in an ordered bytes array
bytes quorumSplits; // quorum splits in a bytes array that correspond to the quorum numbers
bytes quorumNumbers; // quorum numbers in an ordered bytes array
bytes quorumSplits; // quorum splits in a bytes array that correspond to the quorum numbers
}

struct OnDemandPayment {
uint80 totalDeposit;
}

/// @notice Emitted when a reservation is created or updated
event ReservationUpdated(address indexed account, Reservation reservation);
/// @notice Emitted when an on-demand payment is created or updated
event OnDemandPaymentUpdated(address indexed account, uint256 onDemandPayment, uint256 totalDeposit);
/// @notice Emitted when globalSymbolsPerBin is updated
event GlobalSymbolsPerBinUpdated(uint256 previousValue, uint256 newValue);
/// @notice Emitted when reservationBinInterval is updated
event ReservationBinIntervalUpdated(uint256 previousValue, uint256 newValue);
/// @notice Emitted when globalRateBinInterval is updated
event GlobalRateBinIntervalUpdated(uint256 previousValue, uint256 newValue);
event OnDemandPaymentUpdated(address indexed account, uint80 onDemandPayment, uint80 totalDeposit);
/// @notice Emitted when globalSymbolsPerPeriod is updated
event GlobalSymbolsPerPeriodUpdated(uint64 previousValue, uint64 newValue);
/// @notice Emitted when reservationPeriodInterval is updated
event ReservationPeriodIntervalUpdated(uint64 previousValue, uint64 newValue);
/// @notice Emitted when globalRatePeriodInterval is updated
event GlobalRatePeriodIntervalUpdated(uint64 previousValue, uint64 newValue);
/// @notice Emitted when priceParams are updated
event PriceParamsUpdated(
uint256 previousMinNumSymbols,
uint256 newMinNumSymbols,
uint256 previousPricePerSymbol,
uint256 newPricePerSymbol,
uint256 previousPriceUpdateCooldown,
uint256 newPriceUpdateCooldown
uint64 previousMinNumSymbols,
uint64 newMinNumSymbols,
uint64 previousPricePerSymbol,
uint64 newPricePerSymbol,
uint64 previousPriceUpdateCooldown,
uint64 newPriceUpdateCooldown
);

/**
Expand All @@ -54,8 +58,8 @@ interface IPaymentVault {
function getReservations(address[] memory _accounts) external view returns (Reservation[] memory _reservations);

/// @notice Fetches the current total on demand balance of an account
function getOnDemandAmount(address _account) external view returns (uint256);
function getOnDemandTotalDeposit(address _account) external view returns (uint80);

/// @notice Fetches the current total on demand balances for a set of accounts
function getOnDemandAmounts(address[] memory _accounts) external view returns (uint256[] memory _payments);
}
function getOnDemandTotalDeposits(address[] memory _accounts) external view returns (uint80[] memory _payments);
}
69 changes: 36 additions & 33 deletions contracts/src/payments/PaymentVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
* @title Entrypoint for making reservations and on demand payments for EigenDA.
* @author Layr Labs, Inc.
**/
contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {
contract PaymentVault is OwnableUpgradeable, PaymentVaultStorage {

constructor() {
_disableInitializers();
Expand All @@ -25,23 +25,23 @@ contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {

function initialize(
address _initialOwner,
uint256 _minNumSymbols,
uint256 _globalSymbolsPerBin,
uint256 _pricePerSymbol,
uint256 _reservationBinInterval,
uint256 _priceUpdateCooldown,
uint256 _globalRateBinInterval
uint64 _minNumSymbols,
uint64 _pricePerSymbol,
uint64 _priceUpdateCooldown,
uint64 _globalSymbolsPerPeriod,
uint64 _reservationPeriodInterval,
uint64 _globalRatePeriodInterval
) public initializer {
_transferOwnership(_initialOwner);

minNumSymbols = _minNumSymbols;
globalSymbolsPerBin = _globalSymbolsPerBin;
pricePerSymbol = _pricePerSymbol;
reservationBinInterval = _reservationBinInterval;
priceUpdateCooldown = _priceUpdateCooldown;
globalRateBinInterval = _globalRateBinInterval;
lastPriceUpdateTime = uint64(block.timestamp);

lastPriceUpdateTime = block.timestamp;
globalSymbolsPerPeriod = _globalSymbolsPerPeriod;
reservationPeriodInterval = _reservationPeriodInterval;
globalRatePeriodInterval = _globalRatePeriodInterval;
}

/**
Expand All @@ -53,7 +53,7 @@ contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {
address _account,
Reservation memory _reservation
) external onlyOwner {
_checkQuorumSplit(_reservation.quorumNumbers, _reservation.quorumSplits);
_checkQuorumSplit(_reservation.quorumNumbers, _reservation.quorumSplits);
require(_reservation.endTimestamp > _reservation.startTimestamp, "end timestamp must be greater than start timestamp");
reservations[_account] = _reservation;
emit ReservationUpdated(_account, _reservation);
Expand All @@ -64,39 +64,41 @@ contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {
* @param _account is the address to deposit the funds for
*/
function depositOnDemand(address _account) external payable {
_deposit(_account, msg.value);
_deposit(_account, msg.value);
}

function setPriceParams(
uint256 _minNumSymbols,
uint256 _pricePerSymbol,
uint256 _priceUpdateCooldown
uint64 _minNumSymbols,
uint64 _pricePerSymbol,
uint64 _priceUpdateCooldown
) external onlyOwner {
require(block.timestamp >= lastPriceUpdateTime + priceUpdateCooldown, "price update cooldown not surpassed");

emit PriceParamsUpdated(
minNumSymbols, _minNumSymbols,
pricePerSymbol, _pricePerSymbol,
priceUpdateCooldown, _priceUpdateCooldown
);

pricePerSymbol = _pricePerSymbol;
minNumSymbols = _minNumSymbols;
priceUpdateCooldown = _priceUpdateCooldown;
lastPriceUpdateTime = block.timestamp;
lastPriceUpdateTime = uint64(block.timestamp);
}

function setGlobalSymbolsPerBin(uint256 _globalSymbolsPerBin) external onlyOwner {
emit GlobalSymbolsPerBinUpdated(globalSymbolsPerBin, _globalSymbolsPerBin);
globalSymbolsPerBin = _globalSymbolsPerBin;
function setGlobalSymbolsPerPeriod(uint64 _globalSymbolsPerPeriod) external onlyOwner {
emit GlobalSymbolsPerPeriodUpdated(globalSymbolsPerPeriod, _globalSymbolsPerPeriod);
globalSymbolsPerPeriod = _globalSymbolsPerPeriod;
}

function setReservationBinInterval(uint256 _reservationBinInterval) external onlyOwner {
emit ReservationBinIntervalUpdated(reservationBinInterval, _reservationBinInterval);
reservationBinInterval = _reservationBinInterval;
function setReservationPeriodInterval(uint64 _reservationPeriodInterval) external onlyOwner {
emit ReservationPeriodIntervalUpdated(reservationPeriodInterval, _reservationPeriodInterval);
reservationPeriodInterval = _reservationPeriodInterval;
}

function setGlobalRateBinInterval(uint256 _globalRateBinInterval) external onlyOwner {
emit GlobalRateBinIntervalUpdated(globalRateBinInterval, _globalRateBinInterval);
globalRateBinInterval = _globalRateBinInterval;
function setGlobalRatePeriodInterval(uint64 _globalRatePeriodInterval) external onlyOwner {
emit GlobalRatePeriodIntervalUpdated(globalRatePeriodInterval, _globalRatePeriodInterval);
globalRatePeriodInterval = _globalRatePeriodInterval;
}

function withdraw(uint256 _amount) external onlyOwner {
Expand All @@ -116,8 +118,9 @@ contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {
}

function _deposit(address _account, uint256 _amount) internal {
onDemandPayments[_account] += _amount;
emit OnDemandPaymentUpdated(_account, _amount, onDemandPayments[_account]);
require(_amount <= type(uint80).max, "amount must be less than or equal to 80 bits");
onDemandPayments[_account].totalDeposit += uint80(_amount);
emit OnDemandPaymentUpdated(_account, uint80(_amount), onDemandPayments[_account].totalDeposit);
}

/// @notice Fetches the current reservation for an account
Expand All @@ -134,15 +137,15 @@ contract PaymentVault is PaymentVaultStorage, OwnableUpgradeable {
}

/// @notice Fetches the current total on demand balance of an account
function getOnDemandAmount(address _account) external view returns (uint256) {
return onDemandPayments[_account];
function getOnDemandTotalDeposit(address _account) external view returns (uint80) {
return onDemandPayments[_account].totalDeposit;
}

/// @notice Fetches the current total on demand balances for a set of accounts
function getOnDemandAmounts(address[] memory _accounts) external view returns (uint256[] memory _payments) {
_payments = new uint256[](_accounts.length);
function getOnDemandTotalDeposits(address[] memory _accounts) external view returns (uint80[] memory _payments) {
_payments = new uint80[](_accounts.length);
for(uint256 i; i < _accounts.length; ++i){
_payments[i] = onDemandPayments[_accounts[i]];
_payments[i] = onDemandPayments[_accounts[i]].totalDeposit;
}
}
}
26 changes: 13 additions & 13 deletions contracts/src/payments/PaymentVaultStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ import {IPaymentVault} from "../interfaces/IPaymentVault.sol";
abstract contract PaymentVaultStorage is IPaymentVault {

/// @notice minimum chargeable size for on-demand payments
uint256 public minNumSymbols;
uint64 public minNumSymbols;
/// @notice price per symbol in wei
uint256 public pricePerSymbol;
uint64 public pricePerSymbol;
/// @notice cooldown period before the price can be updated again
uint256 public priceUpdateCooldown;
/// @notice maximum number of symbols to disperse per second network-wide for on-demand payments (applied to only ETH and EIGEN)
uint256 public globalSymbolsPerBin;
/// @notice reservation bin duration
uint256 public reservationBinInterval;
/// @notice global rate bin size
uint256 public globalRateBinInterval;

uint64 public priceUpdateCooldown;
/// @notice timestamp of the last price update
uint256 public lastPriceUpdateTime;
uint64 public lastPriceUpdateTime;

/// @notice maximum number of symbols to disperse per second network-wide for on-demand payments (applied to only ETH and EIGEN)
uint64 public globalSymbolsPerPeriod;
/// @notice reservation period interval
uint64 public reservationPeriodInterval;
/// @notice global rate period interval
uint64 public globalRatePeriodInterval;

/// @notice mapping from user address to current reservation
mapping(address => Reservation) public reservations;
/// @notice mapping from user address to current on-demand payment
mapping(address => uint256) public onDemandPayments;
mapping(address => OnDemandPayment) public onDemandPayments;

uint256[42] private __GAP;
uint256[46] private __GAP;
}
4 changes: 3 additions & 1 deletion contracts/test/rollup/MockRollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {IEigenDABatchMetadataStorage} from "../../src/interfaces/IEigenDABatchMe
import {IEigenDASignatureVerifier} from "../../src/interfaces/IEigenDASignatureVerifier.sol";
import {OperatorStateRetriever} from "../../lib/eigenlayer-middleware/src/OperatorStateRetriever.sol";
import {IEigenDARelayRegistry} from "../../src/interfaces/IEigenDARelayRegistry.sol";
import {IPaymentVault} from "../../src/interfaces/IPaymentVault.sol";
import {EigenDARelayRegistry} from "../../src/core/EigenDARelayRegistry.sol";
import {IRegistryCoordinator} from "../../lib/eigenlayer-middleware/src/interfaces/IRegistryCoordinator.sol";
import "../../src/interfaces/IEigenDAStructs.sol";
Expand Down Expand Up @@ -94,7 +95,8 @@ contract MockRollupTest is BLSMockAVSDeployer {
registryCoordinator,
stakeRegistry,
eigenDAThresholdRegistry,
eigenDARelayRegistry
eigenDARelayRegistry,
IPaymentVault(address(0))
);

eigenDAThresholdRegistryImplementation = new EigenDAThresholdRegistry();
Expand Down
Loading
Loading