Skip to content

Commit aef7f8a

Browse files
uri-99entropidelictaturosatiJuArce
authored
feat: implement user batcher payment system (#469)
Co-authored-by: Mariano Nicolini <[email protected]> Co-authored-by: Santos Rosati <[email protected]> Co-authored-by: JuArce <[email protected]>
1 parent f2d7b5b commit aef7f8a

16 files changed

+466
-14
lines changed

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ batcher_fund_service_manager_balance:
183183

184184
batcher_start: ./batcher/aligned-batcher/.env batcher_fund_service_manager_balance
185185
@echo "Starting Batcher..."
186-
@cargo +nightly-2024-04-17 run --manifest-path ./batcher/aligned-batcher/Cargo.toml --release -- --config ./config-files/config.yaml --env-file ./batcher/aligned-batcher/.env
186+
@cargo +nightly-2024-04-17 run --manifest-path ./batcher/aligned-batcher/Cargo.toml --release -- --config ./config-files/config-batcher.yaml --env-file ./batcher/aligned-batcher/.env
187187

188188
install_batcher:
189189
@cargo +nightly-2024-04-17 install --path batcher/aligned-batcher
@@ -522,7 +522,15 @@ upgrade_stake_registry: ## Upgrade Stake Registry
522522
deploy_verify_batch_inclusion_caller:
523523
@echo "Deploying VerifyBatchInclusionCaller contract..."
524524
@. examples/verify/.env && . examples/verify/scripts/deploy_verify_batch_inclusion_caller.sh
525-
525+
526+
deploy_batcher_payment_service:
527+
@echo "Deploying BatcherPayments contract..."
528+
@. contracts/scripts/.env && . contracts/scripts/deploy_batcher_payment_service.sh
529+
530+
upgrade_batcher_payment_service:
531+
@echo "Upgrading BatcherPayments contract..."
532+
@. contracts/scripts/.env && . contracts/scripts/upgrade_batcher_payment_service.sh
533+
526534
build_aligned_contracts:
527535
@cd contracts/src/core && forge build
528536

README_BATCHER_PAYMENTS.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Batcher Payments
2+
3+
## Introduction
4+
5+
To be able to use the batcher, a user must fund its transactions. For this, there is a simple Batcher Payment System.
6+
7+
The Batcher has a Batcher Payments smart contract, which is in charge of recieving user's payments, and which guarantees the batcher can only spend this money to send users' proofs to Aligned.
8+
9+
Users must first deposit into this contract, via a normal transfer to its address.
10+
11+
Then, users can send proofs to the Batcher, the Batcher will preemptively check if the user has funds for this, and once accumulating the whole batch, the Batcher will call its smart contract with the data it has recieved from the users.
12+
13+
The smart contract will then discount the corresponding amount of funds from each of the senders' balances, and create a new Task in Aligned, sending also the corresponding amount of tokens for the batch verification.
14+
15+
Users are also allowed to withdraw extra funds deposited to the Batcher Payments smart contract.
16+
17+
This way, the Batcher can only use User funds to fund the verification of the User's proofs.
18+
19+
## Helpful commands
20+
21+
If you are a User, and want to fund your Batcher so that he can include your proofs in its batch, you can send funds with the following command:
22+
23+
```bash
24+
cast send <batcher_payments_smart_contract_address> --value <desired_amount_to_transfer> --rpc-url <your_rpc_url> --private-key <your_private_key>
25+
```
26+
27+
For example:
28+
```bash
29+
cast send 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0 --value 1ether --rpc-url http://localhost:8545 --private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
30+
```
31+
32+
After sending funds, you can check your current balance:
33+
```bash
34+
cast call 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0 "UserBalances(address)(uint256)" 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720
35+
```
36+
37+
The Batcher will then call something similar to the following command, to submit the batch to Aligned:
38+
```bash
39+
cast send 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0 "createNewTask(bytes32, string, address[], uint256)" 0xc1b2a3c3aec88bb41478922438b0698add6a9a6c57170176115bda61748df59a "http://storage.alignedlayer.com/c1b2a3c3aec88bb41478922438b0698add6a9a6c57170176115bda61748df59a.json" "[0xa0Ee7A142d267C1f36714E4a8F75612F20a79720]" 1000000000000000 --private-key 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
40+
```
41+
42+
Finally, the User can extract excess funds from the smart contract if he desires, or he can leave them there to fund future proofs:
43+
44+
```bash
45+
cast send 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0 "withdraw(uint256)" 1000 --private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
46+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"address":"9965507d1a55bcc2695c58ba16fb37d819b0a4dc","crypto":{"cipher":"aes-128-ctr","ciphertext":"1230c0bf563d579a2ad35f4ad324396ecb9fd54c9332afefee0863c26dbdd5aa","cipherparams":{"iv":"e55c995cbcc803b059ba0edee53b0197"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"75bbc184f52e624d6ee788f2cd595e94c68f510df80ec16da4850cb32cae0f92"},"mac":"a94e76c0b09df894350f916cd9a2f5f349753469ced1fb2283324665981ea191"},"id":"aa19ee46-b861-49cb-be8f-22b85adca142","version":3}

config-files/config-batcher.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Common variables for all the services
2+
# 'production' only prints info and above. 'development' also prints debug
3+
environment: "production"
4+
aligned_layer_deployment_config_file_path: "./contracts/script/output/devnet/alignedlayer_deployment_output.json"
5+
eigen_layer_deployment_config_file_path: "./contracts/script/output/devnet/eigenlayer_deployment_output.json"
6+
eth_rpc_url: "http://localhost:8545"
7+
eth_ws_url: "ws://localhost:8545"
8+
eigen_metrics_ip_port_address: "localhost:9090"
9+
10+
## ECDSA Configurations
11+
ecdsa:
12+
private_key_store_path: "config-files/anvil.batcher.ecdsa.key.json"
13+
private_key_store_password: ""
14+
15+
## Batcher configurations
16+
batcher:
17+
block_interval: 3
18+
batch_size_interval: 10
19+
max_proof_size: 67108864 # 64 MiB
20+
max_batch_size: 268435456 # 256 MiB
21+
eth_ws_reconnects: 99999999999999
22+
pre_verification_is_enabled: true
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
pragma solidity =0.8.12;
2+
3+
import {BatcherPaymentService} from "../../src/core/BatcherPaymentService.sol";
4+
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
5+
6+
import "forge-std/Script.sol";
7+
import "forge-std/StdJson.sol";
8+
9+
contract BatcherPaymentServiceDeployer is Script {
10+
function run(
11+
string memory batcherConfigPath
12+
) external returns (address, address) {
13+
14+
// READ JSON CONFIG DATA
15+
string memory config_data = vm.readFile(batcherConfigPath);
16+
17+
address batcherWallet = stdJson.readAddress(
18+
config_data,
19+
".address.batcherWallet"
20+
);
21+
22+
address alignedLayerServiceManager = stdJson.readAddress(
23+
config_data,
24+
".address.alignedLayerServiceManager"
25+
);
26+
27+
address batcherPaymentServiceOwner = stdJson.readAddress(
28+
config_data,
29+
".permissions.owner"
30+
);
31+
32+
uint256 paymentServiceCreateTaskGasCost = stdJson.readUint(
33+
config_data,
34+
".amounts.paymentServiceCreateTaskGasCost"
35+
);
36+
37+
uint256 serviceManagerCreateTaskGasCost = stdJson.readUint(
38+
config_data,
39+
".amounts.serviceManagerCreateTaskGasCost"
40+
);
41+
42+
uint256 extraUserTxGasCost = stdJson.readUint(
43+
config_data,
44+
".amounts.extraUserTxGasCost"
45+
);
46+
47+
vm.startBroadcast();
48+
49+
BatcherPaymentService batcherPaymentService = new BatcherPaymentService();
50+
ERC1967Proxy proxy = new ERC1967Proxy(address(batcherPaymentService), "");
51+
BatcherPaymentService(payable(address(proxy))).initialize(
52+
alignedLayerServiceManager,
53+
batcherPaymentServiceOwner,
54+
batcherWallet,
55+
paymentServiceCreateTaskGasCost,
56+
serviceManagerCreateTaskGasCost,
57+
extraUserTxGasCost
58+
);
59+
60+
vm.stopBroadcast();
61+
62+
return (
63+
address(proxy),
64+
address(batcherPaymentService)
65+
);
66+
}
67+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"address": {
3+
"batcherWallet": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
4+
"batcherPrivateKey": "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba",
5+
"alignedLayerServiceManager": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8"
6+
},
7+
"amounts": {
8+
"paymentServiceCreateTaskGasCost": 42000,
9+
"serviceManagerCreateTaskGasCost": 60000,
10+
"extraUserTxGasCost": 6500
11+
},
12+
"permissions": {
13+
"owner": "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955"
14+
}
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"address": {
3+
"batcherWallet": "<batcher_wallet_address>",
4+
"alignedLayerServiceManager": "<aligned_layer_service_manager_address>"
5+
},
6+
"amounts": {
7+
"paymentServiceCreateTaskGasCost": 42000,
8+
"serviceManagerCreateTaskGasCost": 60000,
9+
"extraUserTxGasCost": 6500
10+
},
11+
"permissions": {
12+
"owner": "<owner_address>"
13+
}
14+
}

contracts/script/output/devnet/alignedlayer_deployment_output.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"registryCoordinatorImplementation": "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00",
1313
"serviceManagerRouter": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
1414
"stakeRegistry": "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
15-
"stakeRegistryImplementation": "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf"
15+
"stakeRegistryImplementation": "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf",
16+
"batcherPaymentService": "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
17+
"batcherPaymentServiceImplementation": "0x2bdCC0de6bE1f7D2ee689a0342D76F52E8EFABa3"
1618
},
1719
"chainInfo": {
1820
"chainId": 31337,
@@ -25,4 +27,4 @@
2527
"alignedLayerUpgrader": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
2628
"pauserRegistry": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
2729
}
28-
}
30+
}

contracts/script/output/holesky/alignedlayer_deployment_output.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"registryCoordinatorImplementation": "0x85977E7AbcF14F1a88E7BD75eB2653a51649c519",
1313
"serviceManagerRouter": "0x8dA1824Bd43089766247C5B809FCE4a825A6AB25",
1414
"stakeRegistry": "0x51462D5511563A0F97Bb3Ce5475E1c3905b83F4b",
15-
"stakeRegistryImplementation": "0xd1555Be14931C061E06D3CE1D1Daadc1B3c6F8c7"
15+
"stakeRegistryImplementation": "0xd1555Be14931C061E06D3CE1D1Daadc1B3c6F8c7",
16+
"batcherPaymentService": "",
17+
"batcherPaymentServiceImplementation": ""
1618
},
1719
"chainInfo": {
1820
"chainId": 17000,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity =0.8.12;
3+
import {BatcherPaymentService} from "../../src/core/BatcherPaymentService.sol";
4+
5+
import "forge-std/Script.sol";
6+
import "forge-std/StdJson.sol";
7+
8+
contract BatcherPaymentServiceUpgrader is Script {
9+
function run(
10+
string memory alignedLayerDeploymentFilePath
11+
) external returns (address, address) {
12+
13+
string memory aligned_deployment_file = vm.readFile(
14+
alignedLayerDeploymentFilePath
15+
);
16+
17+
vm.startBroadcast();
18+
19+
BatcherPaymentService BatcherPaymentServiceProxy = BatcherPaymentService(payable(
20+
stdJson.readAddress(
21+
aligned_deployment_file,
22+
".addresses.batcherPaymentService"
23+
))
24+
);
25+
26+
BatcherPaymentService newBatcherPaymentServiceImplementation = new BatcherPaymentService();
27+
BatcherPaymentServiceProxy.upgradeToAndCall(address(newBatcherPaymentServiceImplementation), "");
28+
29+
vm.stopBroadcast();
30+
31+
return (address(BatcherPaymentServiceProxy), address(newBatcherPaymentServiceImplementation));
32+
}
33+
}

0 commit comments

Comments
 (0)