Skip to content

Commit

Permalink
feat: payments v1 (#514)
Browse files Browse the repository at this point in the history
* feat: payments w tests and deploy script (#512)

* feat: payments w tests and deploy script

* chore: remove activatedAt and add require

checks payForRange startTimestamp
is multiple of calculationIntervalSeconds

* chore: uint32 for timestamps

* fix: storage off by one

* chore: additional natspec (#519)

* feat: payments w tests and deploy script (#512)

* feat: payments w tests and deploy script

* chore: remove activatedAt and add require

checks payForRange startTimestamp
is multiple of calculationIntervalSeconds

* chore: uint32 for timestamps

* fix: storage off by one

* chore: additional natspec

* chore: requested changes and fixes

* chore: pragmas

* refactor: reuse state read and clean up logic

* fix: relative paths

* chore: update event and tests

* fix: comments and add tests

* test: paused submitRoot flag

* chore: contract organization and added view fn

* chore: require comment

* chore: natspec

* feat: token receiver addresses

* chore: natspec with tokenReceivers

* fix: integration tests

* fix: integration tests

* chore: constants and immutables

* test: additional unit test for max index

* chore: deployed new test contract

* chore: update deployment address

* chore: add single recipient addr

* chore: upgrade payment impl

* chore: upgrade payment impl

* feat: ipfs hashes in distributionRoot

* fix: use CID instead of hash

* chore: remove ipfs

* docs: missing natspec param

* feat: update script to deploy/upgrade

* chore: make calc interval secs to immutable

* fix: add required interfaces

* docs: paymentCoordinator docs (#527)

* docs: paymentCoord docs

* docs: clean up payment docs

* docs: tree structure png
* fix comment

* docs: update single recipient addr

* docs: tweak payment docs for clarity and brevity

---------

Co-authored-by: wadealexc <pragma-services@proton.me>

* refactor: small refactor for readability to surface token transfer and isolate input validation (#530)

* fix payment deploy

* fix: allow verifyInclusion for 0 len proof

also make cumulativeEarnings check strictly gt

* fix: preprod deploy

* fix: merkle diagram and docs

* feat: add payments off-chain assumptions (#533)

* feat: add offchain assumptions to docs; Add offchain variables & token requirement

* docs: simplify off-chain calculcation description

* fix: doc ref

* fix: heading typo

* refactor: make offchain constants internal

* docs: fix typos

* test: single token/earner leaves (#537)

---------

Co-authored-by: wadealexc <pragma-services@proton.me>
Co-authored-by: Alex <18387287+wadealexc@users.noreply.github.com>
Co-authored-by: gpsanant <gpsanant@gmail.com>
Co-authored-by: Yash Patil <40046473+ypatil12@users.noreply.github.com>
  • Loading branch information
5 people authored May 7, 2024
1 parent fd4ce8b commit 3eec97d
Show file tree
Hide file tree
Showing 31 changed files with 4,235 additions and 54 deletions.
14 changes: 14 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This document provides an overview of system components, contracts, and user rol
* [`EigenPodManager`](#eigenpodmanager)
* [`StrategyManager`](#strategymanager)
* [`DelegationManager`](#delegationmanager)
* [`PaymentCoordinator`](#paymentcoordinator)
* [`AVSDirectory`](#avsdirectory)
* [`Slasher`](#slasher)
* [Roles and Actors](#roles-and-actors)
Expand Down Expand Up @@ -66,6 +67,19 @@ The `DelegationManager` sits between the `EigenPodManager` and `StrategyManager`

See full documentation in [`/core/DelegationManager.md`](./core/DelegationManager.md).

#### PaymentCoordinator

| File | Type | Proxy |
| -------- | -------- | -------- |
| [`PaymentCoordinator.sol`](../src/contracts/core/PaymentCoordinator.sol) | Singleton | Transparent proxy |

The `PaymentCoordinator` is the main entry point of submission and claiming of ERC20 payments in EigenLayer. It carries out three basic functions:
* AVSs (via the AVS's contracts) submit "range payments" to their registered Operators and Stakers over a specific time period
* *Off-chain*, the payment updater will use each range payment's time period to apply payment amounts to historical Staker/Operator stake weights. This is consolidated into a merkle root that is posted *on-chain* to the `PaymentCoordinator`, allowing Stakers/Operators to claim their allocated payments.
* Stakers/Operators can claim payments posted by the payment updater.

See full documentation in [`/core/PaymentCoordinator.md`](./core/PaymentCoordinator.md).

#### AVSDirectory

| File | Type | Proxy |
Expand Down
365 changes: 365 additions & 0 deletions docs/core/PaymentCoordinator.md

Large diffs are not rendered by default.

Binary file added docs/images/PaymentCoordinator_Merkle_Tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"chainInfo": {
"chainId": 17000
},
"multisig_addresses": {
"pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7",
"communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7",
"operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d",
"executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
},
"strategies": {
"numStrategies": 0,
"MAX_PER_DEPOSIT": 115792089237316195423570985008687907853269984665640564039457584007913129639935,
"MAX_TOTAL_DEPOSITS": 115792089237316195423570985008687907853269984665640564039457584007913129639935,
"strategiesToDeploy": []
},
"strategyManager": {
"init_strategy_whitelister": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
"init_paused_status": 0
},
"delegationManager": {
"init_paused_status": 0,
"init_minWithdrawalDelayBlocks": 10
},
"paymentCoordinator": {
"init_paused_status": 0,
"CALCULATION_INTERVAL_SECONDS": 604800,
"MAX_PAYMENT_DURATION": 6048000,
"MAX_RETROACTIVE_LENGTH": 7776000,
"MAX_FUTURE_LENGTH": 2592000,
"GENESIS_PAYMENT_TIMESTAMP": 1710979200,
"payment_updater_address": "0x02d9bd32ec711AC8782aEaBF9e1E1309F0965c11",
"activation_delay": 120,
"calculation_interval_seconds": 604800,
"global_operator_commission_bips": 1000
},
"avsDirectory": {
"init_paused_status": 0
},
"slasher": {
"init_paused_status": 0
},
"eigenPod": {
"MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR": 32000000000,
"GENESIS_TIME": 1695902400
},
"eigenPodManager": {
"init_paused_status": 0,
"deneb_fork_timestamp": "1707305664"
},
"delayedWithdrawalRouter": {
"init_paused_status": 0,
"init_withdrawalDelayBlocks": 10
},
"ethPOSDepositAddress": "0x4242424242424242424242424242424242424242",
"beaconOracleAddress": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25"
}
3 changes: 3 additions & 0 deletions script/configs/holesky/Holesky_current_deployment.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
"eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315",
"eigenPodManagerImplementation": "0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B",
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
"paymentCoordinator": "0x0000000000000000000000000000000000000000",
"paymentCoordinatorImplementation": "0x0000000000000000000000000000000000000000",
"slasher": "0xcAe751b75833ef09627549868A04E32679386e7C",
"slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A",
"numStrategiesDeployed": 8,
"strategies": {
"WETH": "0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9",
"rETH": "0x3A8fBdf9e77DFc25d09741f51d3E181b25d0c4E0",
Expand Down
3 changes: 3 additions & 0 deletions script/configs/mainnet/Mainnet_current_deployment.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
"eigenPodManager": "0x91E677b07F7AF907ec9a428aafA9fc14a0d3A338",
"eigenPodManagerImplementation": "0xEB86a5c40FdE917E6feC440aBbCDc80E3862e111",
"emptyContract": "0x1f96861fEFa1065a5A96F20Deb6D8DC3ff48F7f9",
"paymentCoordinator": "0x0000000000000000000000000000000000000000",
"paymentCoordinatorImplementation": "0x0000000000000000000000000000000000000000",
"slasher": "0xD92145c07f8Ed1D392c1B88017934E301CC1c3Cd",
"slasherImplementation": "0xef31c292801f24f16479DD83197F1E6AeBb8d6d8",
"strategyManager": "0x858646372CC42E1A627fcE94aa7A7033e7CF075A",
"strategyManagerImplementation": "0x5d25EEf8CfEdaA47d31fE2346726dE1c21e342Fb",
"numStrategiesDeployed": 12,
"strategies": {
"stETH": "0x93c4b944D05dfe6df7645A86cd2206016c51564D",
"rETH": "0x1BeE69b7dFFfA4E2d53C2a2Df135C388AD25dCD2",
Expand Down
53 changes: 53 additions & 0 deletions script/deploy/holesky/Deploy_Preprod_PaymentCoordinator.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.12;

import "./Deploy_Test_PaymentCoordinator.s.sol";

/**
* @notice Script used for the first deployment of EigenLayer core contracts to Holesky
* anvil --fork-url $RPC_HOLESKY
* Local Fork: Deploy/Upgrade PaymentCoordinator
* forge script script/deploy/holesky/Deploy_Preprod_PaymentCoordinator.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" deploy
* forge script script/deploy/holesky/Deploy_Preprod_PaymentCoordinator.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" upgrade
*
* Holesky testnet: Deploy/Upgrade PaymentCoordinator
* forge script script/deploy/holesky/Deploy_Preprod_PaymentCoordinator.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" deploy
* forge script script/deploy/holesky/Deploy_Preprod_PaymentCoordinator.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" upgrade
*
*/
contract Deploy_Preprod_PaymentCoordinator is Deploy_Test_PaymentCoordinator {
function run(string memory deployArg) external virtual {
_parseInitialDeploymentParams("script/configs/holesky/Deploy_PaymentCoordinator.holesky.config.json");
_parseDeployedContracts("script/output/holesky/M2_deploy_preprod.output.json");

// Overwrite testAddress and multisigs to be EOAowner
testAddress = msg.sender;
executorMultisig = testAddress;
operationsMultisig = testAddress;
pauserMultisig = testAddress;
communityMultisig = testAddress;
STRATEGY_MANAGER_WHITELISTER = testAddress;

// START RECORDING TRANSACTIONS FOR DEPLOYMENT
vm.startBroadcast();

emit log_named_address("Deployer Address", msg.sender);

if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("upgrade"))) {
_upgradePaymentCoordinator();
} else if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("deploy"))) {
_deployPaymentCoordinator();
}

// STOP RECORDING TRANSACTIONS FOR DEPLOYMENT
vm.stopBroadcast();

// Sanity Checks
_verifyContractPointers();
_verifyImplementations();
_verifyContractsInitialized({isInitialDeployment: true});
_verifyInitializationParams();

logAndOutputContractAddresses("script/output/holesky/Deploy_PaymentCoordinator_Preprod.holesky.config.json");
}
}
95 changes: 95 additions & 0 deletions script/deploy/holesky/Deploy_Test_PaymentCoordinator.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.12;

import "../../utils/ExistingDeploymentParser.sol";

/**
* @notice Script used for the first deployment of EigenLayer core contracts to Holesky
* anvil --fork-url $RPC_HOLESKY
* forge script script/deploy/holesky/Deploy_Test_PaymentCoordinator.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv
* forge script script/deploy/holesky/Deploy_Test_PaymentCoordinator.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast -vvvv
*
*/
contract Deploy_Test_PaymentCoordinator is ExistingDeploymentParser {

address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479;

function run() external virtual {
_parseInitialDeploymentParams("script/configs/holesky/Deploy_PaymentCoordinator.holesky.config.json");
_parseDeployedContracts("script/output/holesky/M2_deploy_from_scratch.output.json");

// START RECORDING TRANSACTIONS FOR DEPLOYMENT
vm.startBroadcast();

emit log_named_address("Deployer Address", msg.sender);

_deployPaymentCoordinator();

// STOP RECORDING TRANSACTIONS FOR DEPLOYMENT
vm.stopBroadcast();

// Sanity Checks
_verifyContractPointers();
_verifyImplementations();
_verifyContractsInitialized({isInitialDeployment: true});
_verifyInitializationParams();

logAndOutputContractAddresses("script/output/holesky/Deploy_PaymentCoordinator.holesky.config.json");
}

/**
* @notice Deploy PaymentCoordinator for Holesky
*/
function _deployPaymentCoordinator() internal {
// Deploy PaymentCoordinator proxy and implementation
paymentCoordinatorImplementation = new PaymentCoordinator(
delegationManager,
strategyManager,
PAYMENT_COORDINATOR_CALCULATION_INTERVAL_SECONDS,
PAYMENT_COORDINATOR_MAX_PAYMENT_DURATION,
PAYMENT_COORDINATOR_MAX_RETROACTIVE_LENGTH,
PAYMENT_COORDINATOR_MAX_FUTURE_LENGTH,
PAYMENT_COORDINATOR_GENESIS_PAYMENT_TIMESTAMP
);
paymentCoordinator = PaymentCoordinator(
address(
new TransparentUpgradeableProxy(
address(paymentCoordinatorImplementation),
address(eigenLayerProxyAdmin),
abi.encodeWithSelector(
PaymentCoordinator.initialize.selector,
testAddress, // initOwner
eigenLayerPauserReg,
PAYMENT_COORDINATOR_INIT_PAUSED_STATUS,
PAYMENT_COORDINATOR_UPDATER,
PAYMENT_COORDINATOR_ACTIVATION_DELAY,
PAYMENT_COORDINATOR_GLOBAL_OPERATOR_COMMISSION_BIPS
)
)
)
);


}

/**
* @notice Deploy PaymentCoordinator Implementation for Holesky and upgrade the proxy
*/
function _upgradePaymentCoordinator() internal {
// Deploy PaymentCoordinator proxy and implementation
paymentCoordinatorImplementation = new PaymentCoordinator(
delegationManager,
strategyManager,
PAYMENT_COORDINATOR_CALCULATION_INTERVAL_SECONDS,
PAYMENT_COORDINATOR_MAX_PAYMENT_DURATION,
PAYMENT_COORDINATOR_MAX_RETROACTIVE_LENGTH,
PAYMENT_COORDINATOR_MAX_FUTURE_LENGTH,
PAYMENT_COORDINATOR_GENESIS_PAYMENT_TIMESTAMP
);

eigenLayerProxyAdmin.upgrade(
TransparentUpgradeableProxy(payable(address(paymentCoordinator))),
address(paymentCoordinatorImplementation)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"addresses": {
"avsDirectory": "0x055733000064333CaDDbC92763c58BF0192fFeBf",
"avsDirectoryImplementation": "0xEF5BA995Bc7722fd1e163edF8Dc09375de3d3e3a",
"baseStrategyImplementation": "0xFb83e1D133D0157775eC4F19Ff81478Df1103305",
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
"delayedWithdrawalRouter": "0x642c646053eaf2254f088e9019ACD73d9AE0FA32",
"delayedWithdrawalRouterImplementation": "0xcE8b8D99773a718423F8040a6e52c06a4ce63407",
"delegationManager": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
"delegationManagerImplementation": "0x83f8F8f0BB125F7870F6bfCf76853f874C330D76",
"eigenLayerPauserReg": "0x85Ef7299F8311B25642679edBF02B62FA2212F06",
"eigenLayerProxyAdmin": "0xDB023566064246399b4AE851197a97729C93A6cf",
"eigenPodBeacon": "0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D",
"eigenPodImplementation": "0xe98f9298344527608A1BCC23907B8145F9Cb641c",
"eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315",
"eigenPodManagerImplementation": "0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B",
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
"paymentCoordinator": "0x5fC97864488C2B6fA6E5d2D7730090d7908Db98D",
"paymentCoordinatorImplementation": "0x4B034d112b8d422665B13F791A4e1104894e0463",
"slasher": "0xcAe751b75833ef09627549868A04E32679386e7C",
"slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A",
"strategies": "",
"strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6",
"strategyManagerImplementation": "0x59f766A603C53f3AC8Be43bBe158c1519b193a18"
},
"chainInfo": {
"chainId": 17000,
"deploymentBlock": 1471383
},
"parameters": {
"communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7",
"executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
"operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d",
"pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7",
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"addresses": {
"avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC",
"avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A",
"baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40",
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
"delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa",
"delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38",
"delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC",
"delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1",
"eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1",
"eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B",
"eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC",
"eigenPodImplementation": "0x2D6c7f9862BD80Cf0d9d93FC6b513D69E7Db7869",
"eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff",
"eigenPodManagerImplementation": "0xc5B857A92245f64e9D90cCc5b096Db82eB77eB5c",
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
"paymentCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0",
"paymentCoordinatorImplementation": "0xC9366ab4A299e0937EC15A6C256C4481C05A24fD",
"slasher": "0x12699471dF8dca329C76D72823B1b79d55709384",
"slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0",
"strategies": "",
"strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a",
"strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199"
},
"chainInfo": {
"chainId": 17000,
"deploymentBlock": 1477016
},
"parameters": {
"communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
}
}
Loading

0 comments on commit 3eec97d

Please sign in to comment.