Skip to content

Commit 3eec97d

Browse files
8sunyuanwadealexcgpsanantypatil12
authored
feat: payments v1 (#514)
* 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 <[email protected]> * 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 <[email protected]> Co-authored-by: Alex <[email protected]> Co-authored-by: gpsanant <[email protected]> Co-authored-by: Yash Patil <[email protected]>
1 parent fd4ce8b commit 3eec97d

31 files changed

+4235
-54
lines changed

docs/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This document provides an overview of system components, contracts, and user rol
1212
* [`EigenPodManager`](#eigenpodmanager)
1313
* [`StrategyManager`](#strategymanager)
1414
* [`DelegationManager`](#delegationmanager)
15+
* [`PaymentCoordinator`](#paymentcoordinator)
1516
* [`AVSDirectory`](#avsdirectory)
1617
* [`Slasher`](#slasher)
1718
* [Roles and Actors](#roles-and-actors)
@@ -66,6 +67,19 @@ The `DelegationManager` sits between the `EigenPodManager` and `StrategyManager`
6667

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

70+
#### PaymentCoordinator
71+
72+
| File | Type | Proxy |
73+
| -------- | -------- | -------- |
74+
| [`PaymentCoordinator.sol`](../src/contracts/core/PaymentCoordinator.sol) | Singleton | Transparent proxy |
75+
76+
The `PaymentCoordinator` is the main entry point of submission and claiming of ERC20 payments in EigenLayer. It carries out three basic functions:
77+
* AVSs (via the AVS's contracts) submit "range payments" to their registered Operators and Stakers over a specific time period
78+
* *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.
79+
* Stakers/Operators can claim payments posted by the payment updater.
80+
81+
See full documentation in [`/core/PaymentCoordinator.md`](./core/PaymentCoordinator.md).
82+
6983
#### AVSDirectory
7084

7185
| File | Type | Proxy |

docs/core/PaymentCoordinator.md

Lines changed: 365 additions & 0 deletions
Large diffs are not rendered by default.
265 KB
Loading
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"chainInfo": {
3+
"chainId": 17000
4+
},
5+
"multisig_addresses": {
6+
"pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7",
7+
"communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7",
8+
"operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d",
9+
"executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
10+
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
11+
},
12+
"strategies": {
13+
"numStrategies": 0,
14+
"MAX_PER_DEPOSIT": 115792089237316195423570985008687907853269984665640564039457584007913129639935,
15+
"MAX_TOTAL_DEPOSITS": 115792089237316195423570985008687907853269984665640564039457584007913129639935,
16+
"strategiesToDeploy": []
17+
},
18+
"strategyManager": {
19+
"init_strategy_whitelister": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
20+
"init_paused_status": 0
21+
},
22+
"delegationManager": {
23+
"init_paused_status": 0,
24+
"init_minWithdrawalDelayBlocks": 10
25+
},
26+
"paymentCoordinator": {
27+
"init_paused_status": 0,
28+
"CALCULATION_INTERVAL_SECONDS": 604800,
29+
"MAX_PAYMENT_DURATION": 6048000,
30+
"MAX_RETROACTIVE_LENGTH": 7776000,
31+
"MAX_FUTURE_LENGTH": 2592000,
32+
"GENESIS_PAYMENT_TIMESTAMP": 1710979200,
33+
"payment_updater_address": "0x02d9bd32ec711AC8782aEaBF9e1E1309F0965c11",
34+
"activation_delay": 120,
35+
"calculation_interval_seconds": 604800,
36+
"global_operator_commission_bips": 1000
37+
},
38+
"avsDirectory": {
39+
"init_paused_status": 0
40+
},
41+
"slasher": {
42+
"init_paused_status": 0
43+
},
44+
"eigenPod": {
45+
"MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR": 32000000000,
46+
"GENESIS_TIME": 1695902400
47+
},
48+
"eigenPodManager": {
49+
"init_paused_status": 0,
50+
"deneb_fork_timestamp": "1707305664"
51+
},
52+
"delayedWithdrawalRouter": {
53+
"init_paused_status": 0,
54+
"init_withdrawalDelayBlocks": 10
55+
},
56+
"ethPOSDepositAddress": "0x4242424242424242424242424242424242424242",
57+
"beaconOracleAddress": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25"
58+
}

script/configs/holesky/Holesky_current_deployment.config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
"eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315",
1616
"eigenPodManagerImplementation": "0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B",
1717
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
18+
"paymentCoordinator": "0x0000000000000000000000000000000000000000",
19+
"paymentCoordinatorImplementation": "0x0000000000000000000000000000000000000000",
1820
"slasher": "0xcAe751b75833ef09627549868A04E32679386e7C",
1921
"slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A",
22+
"numStrategiesDeployed": 8,
2023
"strategies": {
2124
"WETH": "0x80528D6e9A2BAbFc766965E0E26d5aB08D9CFaF9",
2225
"rETH": "0x3A8fBdf9e77DFc25d09741f51d3E181b25d0c4E0",

script/configs/mainnet/Mainnet_current_deployment.config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
"eigenPodManager": "0x91E677b07F7AF907ec9a428aafA9fc14a0d3A338",
1616
"eigenPodManagerImplementation": "0xEB86a5c40FdE917E6feC440aBbCDc80E3862e111",
1717
"emptyContract": "0x1f96861fEFa1065a5A96F20Deb6D8DC3ff48F7f9",
18+
"paymentCoordinator": "0x0000000000000000000000000000000000000000",
19+
"paymentCoordinatorImplementation": "0x0000000000000000000000000000000000000000",
1820
"slasher": "0xD92145c07f8Ed1D392c1B88017934E301CC1c3Cd",
1921
"slasherImplementation": "0xef31c292801f24f16479DD83197F1E6AeBb8d6d8",
2022
"strategyManager": "0x858646372CC42E1A627fcE94aa7A7033e7CF075A",
2123
"strategyManagerImplementation": "0x5d25EEf8CfEdaA47d31fE2346726dE1c21e342Fb",
24+
"numStrategiesDeployed": 12,
2225
"strategies": {
2326
"stETH": "0x93c4b944D05dfe6df7645A86cd2206016c51564D",
2427
"rETH": "0x1BeE69b7dFFfA4E2d53C2a2Df135C388AD25dCD2",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "./Deploy_Test_PaymentCoordinator.s.sol";
5+
6+
/**
7+
* @notice Script used for the first deployment of EigenLayer core contracts to Holesky
8+
* anvil --fork-url $RPC_HOLESKY
9+
* Local Fork: Deploy/Upgrade PaymentCoordinator
10+
* 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
11+
* 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
12+
*
13+
* Holesky testnet: Deploy/Upgrade PaymentCoordinator
14+
* 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
15+
* 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
16+
*
17+
*/
18+
contract Deploy_Preprod_PaymentCoordinator is Deploy_Test_PaymentCoordinator {
19+
function run(string memory deployArg) external virtual {
20+
_parseInitialDeploymentParams("script/configs/holesky/Deploy_PaymentCoordinator.holesky.config.json");
21+
_parseDeployedContracts("script/output/holesky/M2_deploy_preprod.output.json");
22+
23+
// Overwrite testAddress and multisigs to be EOAowner
24+
testAddress = msg.sender;
25+
executorMultisig = testAddress;
26+
operationsMultisig = testAddress;
27+
pauserMultisig = testAddress;
28+
communityMultisig = testAddress;
29+
STRATEGY_MANAGER_WHITELISTER = testAddress;
30+
31+
// START RECORDING TRANSACTIONS FOR DEPLOYMENT
32+
vm.startBroadcast();
33+
34+
emit log_named_address("Deployer Address", msg.sender);
35+
36+
if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("upgrade"))) {
37+
_upgradePaymentCoordinator();
38+
} else if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("deploy"))) {
39+
_deployPaymentCoordinator();
40+
}
41+
42+
// STOP RECORDING TRANSACTIONS FOR DEPLOYMENT
43+
vm.stopBroadcast();
44+
45+
// Sanity Checks
46+
_verifyContractPointers();
47+
_verifyImplementations();
48+
_verifyContractsInitialized({isInitialDeployment: true});
49+
_verifyInitializationParams();
50+
51+
logAndOutputContractAddresses("script/output/holesky/Deploy_PaymentCoordinator_Preprod.holesky.config.json");
52+
}
53+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "../../utils/ExistingDeploymentParser.sol";
5+
6+
/**
7+
* @notice Script used for the first deployment of EigenLayer core contracts to Holesky
8+
* anvil --fork-url $RPC_HOLESKY
9+
* forge script script/deploy/holesky/Deploy_Test_PaymentCoordinator.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv
10+
* forge script script/deploy/holesky/Deploy_Test_PaymentCoordinator.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast -vvvv
11+
*
12+
*/
13+
contract Deploy_Test_PaymentCoordinator is ExistingDeploymentParser {
14+
15+
address testAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479;
16+
17+
function run() external virtual {
18+
_parseInitialDeploymentParams("script/configs/holesky/Deploy_PaymentCoordinator.holesky.config.json");
19+
_parseDeployedContracts("script/output/holesky/M2_deploy_from_scratch.output.json");
20+
21+
// START RECORDING TRANSACTIONS FOR DEPLOYMENT
22+
vm.startBroadcast();
23+
24+
emit log_named_address("Deployer Address", msg.sender);
25+
26+
_deployPaymentCoordinator();
27+
28+
// STOP RECORDING TRANSACTIONS FOR DEPLOYMENT
29+
vm.stopBroadcast();
30+
31+
// Sanity Checks
32+
_verifyContractPointers();
33+
_verifyImplementations();
34+
_verifyContractsInitialized({isInitialDeployment: true});
35+
_verifyInitializationParams();
36+
37+
logAndOutputContractAddresses("script/output/holesky/Deploy_PaymentCoordinator.holesky.config.json");
38+
}
39+
40+
/**
41+
* @notice Deploy PaymentCoordinator for Holesky
42+
*/
43+
function _deployPaymentCoordinator() internal {
44+
// Deploy PaymentCoordinator proxy and implementation
45+
paymentCoordinatorImplementation = new PaymentCoordinator(
46+
delegationManager,
47+
strategyManager,
48+
PAYMENT_COORDINATOR_CALCULATION_INTERVAL_SECONDS,
49+
PAYMENT_COORDINATOR_MAX_PAYMENT_DURATION,
50+
PAYMENT_COORDINATOR_MAX_RETROACTIVE_LENGTH,
51+
PAYMENT_COORDINATOR_MAX_FUTURE_LENGTH,
52+
PAYMENT_COORDINATOR_GENESIS_PAYMENT_TIMESTAMP
53+
);
54+
paymentCoordinator = PaymentCoordinator(
55+
address(
56+
new TransparentUpgradeableProxy(
57+
address(paymentCoordinatorImplementation),
58+
address(eigenLayerProxyAdmin),
59+
abi.encodeWithSelector(
60+
PaymentCoordinator.initialize.selector,
61+
testAddress, // initOwner
62+
eigenLayerPauserReg,
63+
PAYMENT_COORDINATOR_INIT_PAUSED_STATUS,
64+
PAYMENT_COORDINATOR_UPDATER,
65+
PAYMENT_COORDINATOR_ACTIVATION_DELAY,
66+
PAYMENT_COORDINATOR_GLOBAL_OPERATOR_COMMISSION_BIPS
67+
)
68+
)
69+
)
70+
);
71+
72+
73+
}
74+
75+
/**
76+
* @notice Deploy PaymentCoordinator Implementation for Holesky and upgrade the proxy
77+
*/
78+
function _upgradePaymentCoordinator() internal {
79+
// Deploy PaymentCoordinator proxy and implementation
80+
paymentCoordinatorImplementation = new PaymentCoordinator(
81+
delegationManager,
82+
strategyManager,
83+
PAYMENT_COORDINATOR_CALCULATION_INTERVAL_SECONDS,
84+
PAYMENT_COORDINATOR_MAX_PAYMENT_DURATION,
85+
PAYMENT_COORDINATOR_MAX_RETROACTIVE_LENGTH,
86+
PAYMENT_COORDINATOR_MAX_FUTURE_LENGTH,
87+
PAYMENT_COORDINATOR_GENESIS_PAYMENT_TIMESTAMP
88+
);
89+
90+
eigenLayerProxyAdmin.upgrade(
91+
TransparentUpgradeableProxy(payable(address(paymentCoordinator))),
92+
address(paymentCoordinatorImplementation)
93+
);
94+
}
95+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"addresses": {
3+
"avsDirectory": "0x055733000064333CaDDbC92763c58BF0192fFeBf",
4+
"avsDirectoryImplementation": "0xEF5BA995Bc7722fd1e163edF8Dc09375de3d3e3a",
5+
"baseStrategyImplementation": "0xFb83e1D133D0157775eC4F19Ff81478Df1103305",
6+
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
7+
"delayedWithdrawalRouter": "0x642c646053eaf2254f088e9019ACD73d9AE0FA32",
8+
"delayedWithdrawalRouterImplementation": "0xcE8b8D99773a718423F8040a6e52c06a4ce63407",
9+
"delegationManager": "0xA44151489861Fe9e3055d95adC98FbD462B948e7",
10+
"delegationManagerImplementation": "0x83f8F8f0BB125F7870F6bfCf76853f874C330D76",
11+
"eigenLayerPauserReg": "0x85Ef7299F8311B25642679edBF02B62FA2212F06",
12+
"eigenLayerProxyAdmin": "0xDB023566064246399b4AE851197a97729C93A6cf",
13+
"eigenPodBeacon": "0x7261C2bd75a7ACE1762f6d7FAe8F63215581832D",
14+
"eigenPodImplementation": "0xe98f9298344527608A1BCC23907B8145F9Cb641c",
15+
"eigenPodManager": "0x30770d7E3e71112d7A6b7259542D1f680a70e315",
16+
"eigenPodManagerImplementation": "0x5265C162f7d5F3fE3175a78828ab16bf5E324a7B",
17+
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
18+
"paymentCoordinator": "0x5fC97864488C2B6fA6E5d2D7730090d7908Db98D",
19+
"paymentCoordinatorImplementation": "0x4B034d112b8d422665B13F791A4e1104894e0463",
20+
"slasher": "0xcAe751b75833ef09627549868A04E32679386e7C",
21+
"slasherImplementation": "0x99715D255E34a39bE9943b82F281CA734bcF345A",
22+
"strategies": "",
23+
"strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6",
24+
"strategyManagerImplementation": "0x59f766A603C53f3AC8Be43bBe158c1519b193a18"
25+
},
26+
"chainInfo": {
27+
"chainId": 17000,
28+
"deploymentBlock": 1471383
29+
},
30+
"parameters": {
31+
"communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7",
32+
"executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348",
33+
"operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d",
34+
"pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7",
35+
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"addresses": {
3+
"avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC",
4+
"avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A",
5+
"baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40",
6+
"beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25",
7+
"delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa",
8+
"delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38",
9+
"delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC",
10+
"delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1",
11+
"eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1",
12+
"eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B",
13+
"eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC",
14+
"eigenPodImplementation": "0x2D6c7f9862BD80Cf0d9d93FC6b513D69E7Db7869",
15+
"eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff",
16+
"eigenPodManagerImplementation": "0xc5B857A92245f64e9D90cCc5b096Db82eB77eB5c",
17+
"emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2",
18+
"paymentCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0",
19+
"paymentCoordinatorImplementation": "0xC9366ab4A299e0937EC15A6C256C4481C05A24fD",
20+
"slasher": "0x12699471dF8dca329C76D72823B1b79d55709384",
21+
"slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0",
22+
"strategies": "",
23+
"strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a",
24+
"strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199"
25+
},
26+
"chainInfo": {
27+
"chainId": 17000,
28+
"deploymentBlock": 1477016
29+
},
30+
"parameters": {
31+
"communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
32+
"executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
33+
"operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
34+
"pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479",
35+
"timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D"
36+
}
37+
}

0 commit comments

Comments
 (0)